create-qs 0.8.23 → 0.8.24

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/index.js CHANGED
@@ -1804,7 +1804,7 @@ async function processFiles(options) {
1804
1804
  variables.set("WEB_PACKAGE_NAME", options.webModulePackage);
1805
1805
  variables.set("API_PACKAGE", options.apiPackage);
1806
1806
  variables.set("API_ARTIFACT_ID", options.apiArtifactId);
1807
- variables.set("QUICKSILVER_VERSION", "0.8.23");
1807
+ variables.set("QUICKSILVER_VERSION", "0.8.24");
1808
1808
  variables.set("MODULE_ID", randomUUID());
1809
1809
  variables.set("DB_PREFIX", toDbPrefix(options.name));
1810
1810
  const menu = renderModuleMenu(options.moduleMenu, options.platformModules);
@@ -1866,7 +1866,7 @@ if (process.argv.some((arg) => arg === "--version" || arg === "-v")) {
1866
1866
  console.log(getCliVersion());
1867
1867
  process.exit(0);
1868
1868
  }
1869
- var program = new Command().name("create-qs").description("Create a new Quicksilver application").version("0.8.23", "-v, --version").argument("[project-name]", "Name of the project").option("-c, --module-code <code>", "Full module code (e.g., power_crm.sales)").option("-d, --module-directory <directory>", "Module directory name (e.g., sales)").option("-n, --module-namespace <code>", "Prefix of unit/table, defaults to the initials of the module code (e.g., pcs)").option("-p, --api-package <package>", "JVM package for Kotlin files (e.g., com.company.crm)").option("-a, --api-artifact-id <artifactId>", "Module artifact ID in repository (e.g., power-crm-module-sales)").option("-w, --web-module-package <package>", "Web module package name (e.g., @powercrm/module-sales-web)").option("-m, --modules <codes>", "Modules to depend on, comma separated (e.g., quicksilver.org)").option("--module-menu <name>", "Create the module's top-level menu in the left nav, with this label").option("--no-module-menu", "Do not create a top-level menu").option("-y, --yes", "Skip prompts and use defaults").action(async (projectName, options) => {
1869
+ var program = new Command().name("create-qs").description("Create a new Quicksilver application").version("0.8.24", "-v, --version").argument("[project-name]", "Name of the project").option("-c, --module-code <code>", "Full module code (e.g., power_crm.sales)").option("-d, --module-directory <directory>", "Module directory name (e.g., sales)").option("-n, --module-namespace <code>", "Prefix of unit/table, defaults to the initials of the module code (e.g., pcs)").option("-p, --api-package <package>", "JVM package for Kotlin files (e.g., com.company.crm)").option("-a, --api-artifact-id <artifactId>", "Module artifact ID in repository (e.g., power-crm-module-sales)").option("-w, --web-module-package <package>", "Web module package name (e.g., @powercrm/module-sales-web)").option("-m, --modules <codes>", "Modules to depend on, comma separated (e.g., quicksilver.org)").option("--module-menu <name>", "Create the module's top-level menu in the left nav, with this label").option("--no-module-menu", "Do not create a top-level menu").option("-y, --yes", "Skip prompts and use defaults").action(async (projectName, options) => {
1870
1870
  applyPromptTexts();
1871
1871
  console.log(chalk4.cyan(`
1872
1872
  ${t("banner")}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-qs",
3
- "version": "0.8.23",
3
+ "version": "0.8.24",
4
4
  "description": "Create a full-stack Quicksilver project with a single command",
5
5
  "type": "module",
6
6
  "bin": {
@@ -105,6 +105,7 @@ Project scripts (see `scripts` in `package.json`; the database dialect scripts l
105
105
  ```bash
106
106
  pnpm dev # Full dev environment (API + web), ports 6286 / 6288
107
107
  pnpm dev:h2 # A second, isolated instance (own database and Atomikos directory)
108
+ pnpm dev:fresh # A separate instance (ports 6280 / 6281) whose own database is rebuilt from init and demo data at every start
108
109
  pnpm build # Full build (backend + frontend)
109
110
  pnpm test:api # Backend tests
110
111
  pnpm lint # ESLint (pnpm lint:fix to autofix)
@@ -175,16 +176,17 @@ you are unsure what a target would actually do.
175
176
  **An AI agent starts `pnpm dev:h2`, never `pnpm dev`.**
176
177
 
177
178
  `pnpm dev` (web 6286 / api 6288) belongs to the person you are working with. It may well be running
178
- already, and it is backed by the H2 file database `run/api/local/data/h2/database1`, which keeps
179
+ already, and it is backed by the H2 file database `run/api/local/data/h2/dev`, which keeps
179
180
  their data between starts: with `auto-init.draft-sync: true`, every start runs the upgrade drafts that
180
181
  changed since the last one. Starting or restarting it yourself interrupts them and runs your
181
182
  half-finished drafts against their data, so taking it over does not just steal a port.
182
183
 
183
- `pnpm dev:h2` (6210 / 6211) is the isolated instance: its own database (`database2`), its own log
184
+ `pnpm dev:h2` (6210 / 6211) is the isolated instance: its own database (`h2`), its own log
184
185
  directory and its own Atomikos directory, so it can run side by side with theirs. The other dialect
185
186
  scripts (`dev:postgresql` 6220/6221, `dev:mariadb` 6230/6231, `dev:mssql` 6240/6241, `dev:oracle`
186
187
  6250/6251) are equally isolated, but they need a real server: fill in the placeholders in
187
- `run/api/config/application-<dialect>.yaml` first.
188
+ `run/api/config/application-<dialect>.yaml` first. `pnpm dev:fresh` (6280 / 6281) is isolated in the
189
+ same way, on the H2 database `fresh`, which it drops and rebuilds from init and demo data at every start.
188
190
 
189
191
  Two more rules:
190
192
 
@@ -194,6 +196,9 @@ Two more rules:
194
196
  something in 9000–9999; if it is still taken, Vite fails outright — pick another.
195
197
  - **Stop the server you started.** Especially after Playwright: leaving it running holds the port
196
198
  and the database file.
199
+ - **Rebuild when the database no longer matches the branch.** After switching branches, or when
200
+ earlier experiments left the database in a state you cannot explain, start once with
201
+ `pnpm dev:h2 --fresh`. Draft sync never undoes a change that was taken out of a draft.
197
202
 
198
203
  ## Signing in locally
199
204
 
@@ -219,8 +224,8 @@ The profile file is the source of truth for where the data actually lives. Read
219
224
  started) and take the datasource from there; note that paths in it are relative to `run/api`, which
220
225
  is the working directory of the API process.
221
226
 
222
- For the default H2 profiles that means a file — `run/api/local/data/h2/database1` for `pnpm dev`,
223
- `database2` for `pnpm dev:h2` — which you can open with any H2 client. For the other dialects,
227
+ For the default H2 profiles that means a file — `run/api/local/data/h2/dev` for `pnpm dev`,
228
+ `h2` for `pnpm dev:h2` — which you can open with any H2 client. For the other dialects,
224
229
  connect with your usual client using the host, port, user and password from that same file.
225
230
 
226
231
  The development database is kept between starts. With `auto-init.draft-sync: true`, every start runs
@@ -233,8 +238,8 @@ existing data, such as filling a new column, goes into the draft only. Changes t
233
238
  out of the draft, since demo data runs on fresh installs only. Imperative commands in a draft (`@sql`,
234
239
  `$update`, `$delete` ...) run once per `$key`; to run a changed one again, give it a new `$key`.
235
240
  `$place` is the exception: it runs again whenever its draft runs. To rebuild the database from the
236
- data files under `data/init/` and `data/demo/`, set `drop-first: true` in a profile override for one
237
- start, then set it back.
241
+ data files under `data/init/` and `data/demo/`, add `--fresh` to the start command for one start
242
+ (`pnpm dev:h2 --fresh`). It changes no config file, and the next start without it keeps the data again.
238
243
 
239
244
  ## Development skills
240
245
 
@@ -5,7 +5,7 @@ This folder holds demo data, rows that exist only to show and test the product,
5
5
  - Put the rows in `.jsons` files in this folder or in subfolders of it. Other files, such as this README, are skipped.
6
6
  - On a fresh install of the module, the files run after everything in `data/init/`, sorted by name level by level with each subfolder run where it sorts, and they can refer to rows written there.
7
7
  - Development and test profiles load demo data, as set by `quicksilver.datasource.auto-init.demo-data` in `run/api/config/application-dev.yaml`. On a production install the installer asks first, and does not load it by default.
8
- - A module that is already installed never loads demo data. Draft sync does not run these files either, so an existing database does not pick up files added or changed here. To load them, set `drop-first: true` for one start, then set it back to `false`. The rebuild clears the whole development database, including rows entered through the UI.
8
+ - A module that is already installed never loads demo data. Draft sync does not run these files either, so an existing database does not pick up files added or changed here. To load them, start once with `pnpm dev --fresh`, or add `--fresh` to the dialect script you use. The rebuild clears the whole development database, including rows entered through the UI.
9
9
  - Do not copy demo rows into `data/upgrade/draft.jsons`. Upgrades never load demo data.
10
10
 
11
11
  The rules for data files are in section 10 of [`.agents/skills/qs-jsons/references/json-command.md`](../../../../../.agents/skills/qs-jsons/references/json-command.md), and in the developer manual at [`.quicksilver/manual/en-US/06-data.md`](../../../../../.quicksilver/manual/en-US/06-data.md). Both are written by `pnpm install`.
@@ -10,6 +10,7 @@
10
10
  "scripts": {
11
11
  "// --- start dev servers -------------------------------------------": "",
12
12
  "dev": "quicksilver dev",
13
+ "dev:fresh": "PORT=6280 API_PORT=6281 SPRING_PROFILES_ACTIVE=dev,fresh quicksilver dev --fresh",
13
14
  "dev:h2": "PORT=6210 API_PORT=6211 SPRING_PROFILES_ACTIVE=dev,h2 quicksilver dev",
14
15
  "dev:postgresql": "PORT=6220 API_PORT=6221 SPRING_PROFILES_ACTIVE=dev,postgresql quicksilver dev",
15
16
  "dev:mariadb": "PORT=6230 API_PORT=6231 SPRING_PROFILES_ACTIVE=dev,mariadb quicksilver dev",
@@ -25,13 +25,13 @@ catalogs:
25
25
  client:
26
26
  "@qs-charts/adapter-preact": "0.2.11"
27
27
  "@qs-charts/core": "0.2.11"
28
- "@qs-elements/web": "1.0.158"
29
- "@qs-elements/web-preact": "1.0.158"
28
+ "@qs-elements/web": "1.0.163"
29
+ "@qs-elements/web-preact": "1.0.163"
30
30
  quicksilver:
31
- "@qs-platform/cli": "0.8.23"
32
- "@qs-platform/preset-vite-web": "0.8.23"
33
- "@qs-platform/web-module-core": "0.8.23"
34
- "@qs-platform/web-module-org": "0.8.23"
31
+ "@qs-platform/cli": "0.8.24"
32
+ "@qs-platform/preset-vite-web": "0.8.24"
33
+ "@qs-platform/web-module-core": "0.8.24"
34
+ "@qs-platform/web-module-org": "0.8.24"
35
35
  tooling:
36
36
  "@types/node": "^26.4.0"
37
37
  "sass": "^1.103.1"
@@ -33,7 +33,7 @@ database after this project — a project called `power-crm` gets `power_crm_dev
33
33
  Quicksilver products can share one database server without colliding. Two files sit outside that
34
34
  rule: Oracle, whose "database" is a PDB with a name fixed by the container image (`FREEPDB1`), and
35
35
  the H2 profiles, whose databases are plain files under this project's own `local/data/h2/`
36
- (`database1` for `dev`, `database2` for `dev:h2`) and so have nothing to collide with. The
36
+ (`dev` for `pnpm dev`, `h2` for `pnpm dev:h2`) and so have nothing to collide with. The
37
37
  datasource list is replaced as a whole, so when you change one entry, keep the other one listed
38
38
  as well.
39
39
 
@@ -60,16 +60,16 @@ dialects. Every other dialect listed above ships with its driver.
60
60
 
61
61
  The `dev` profile turns on `draft-sync` and turns off `drop-first`. Every start runs the upgrade
62
62
  drafts that changed since the last start, and keeps the data already in the dev database. To
63
- rebuild the database from init and demo data, set `drop-first: true` for one start and then set it
64
- back. Switching `draft-sync` on or off also needs one such rebuild: the two modes record drafts
65
- differently, and startup refuses a database built in the other mode.
63
+ rebuild the database from init and demo data, start once with `pnpm dev --fresh`, or add `--fresh` to
64
+ a dialect script, as in `pnpm dev:h2 --fresh`. The option turns `drop-first` on for that start only
65
+ and changes no config file. Switching `draft-sync` on or off also needs one such rebuild: the two
66
+ modes record drafts differently, and startup refuses a database built in the other mode.
66
67
 
67
68
  ## Local edits
68
69
 
69
70
  `application-dev.yaml` is committed, but **by convention your local edits to it are not** — a
70
- different database host, `drop-first` turned on for a rebuild, a different
71
- `fail-on-unregistered-data-source`. Commit it only when you are deliberately changing the team
72
- default, and say so in the commit message.
71
+ different database host, a different `fail-on-unregistered-data-source`. Commit it only when you
72
+ are deliberately changing the team default, and say so in the commit message.
73
73
 
74
74
  For an override that never enters version control, point `QUICKSILVER_CONFIG_LOCATION` at a config
75
75
  directory of your own: it is appended to the tail of `spring.config.location`, so it wins over
@@ -10,11 +10,11 @@ quicksilver:
10
10
  # Keep the quotes around passwords: special characters (# : @ ...) then paste in as is.
11
11
  items:
12
12
  - code: metadata
13
- url: "jdbc:h2:./local/data/h2/database1;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
13
+ url: "jdbc:h2:./local/data/h2/dev;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
14
14
  user: sa
15
15
  password: "sa"
16
16
  - code: business
17
- url: "jdbc:h2:./local/data/h2/database1;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
17
+ url: "jdbc:h2:./local/data/h2/dev;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
18
18
  user: sa
19
19
  password: "sa"
20
20
  # Each ac_table row records the datasource its table lives in. When a row names a code that is
@@ -27,15 +27,16 @@ quicksilver:
27
27
  # only when quicksilver.application.mode is development. In production the installer does it.
28
28
  enabled: true
29
29
  # Drop the tables and views that Quicksilver manages before provisioning, so the database is
30
- # rebuilt from init and demo data. Set drop-first: true for one start, then set it back to false.
30
+ # rebuilt from init and demo data. Keep it false here. To rebuild, start once with
31
+ # `pnpm dev --fresh`, or add --fresh to a dialect script, which turns it on for that start only.
31
32
  drop-first: false
32
33
  # Draft sync. Every start runs the upgrade drafts that changed since the last start. Data in
33
34
  # the dev database is kept, including rows entered through the UI. Switching draft-sync on or
34
- # off needs one rebuild with drop-first.
35
+ # off needs one rebuild with --fresh.
35
36
  draft-sync: true
36
37
  # Demo data: on a fresh install of a module, the .jsons files in its data/demo/ run after its
37
38
  # init. A database that already exists does not pick up demo files added later, rebuild it with
38
- # drop-first as described above.
39
+ # --fresh as described above.
39
40
  demo-data: true
40
41
  webhook:
41
42
  # Webhook targets that resolve to a private or loopback address (10.0.0.0/8, 127.0.0.0/8, ...)
@@ -0,0 +1,23 @@
1
+ #
2
+ # Overlay for the `fresh` profile used by `pnpm dev:fresh`: only the keys that differ from
3
+ # application-dev.yaml, everything else is inherited key by key. It has a database of its own, which
4
+ # the script drops and rebuilds from init and demo data at every start, so the `pnpm dev` database
5
+ # is never touched.
6
+ #
7
+ logging:
8
+ file.path: local/log/application/fresh
9
+
10
+ quicksilver:
11
+ datasource:
12
+ # Keep the quotes around passwords: special characters (# : @ ...) then paste in as is.
13
+ items:
14
+ - code: metadata
15
+ url: "jdbc:h2:./local/data/h2/fresh;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
16
+ user: sa
17
+ password: "sa"
18
+ - code: business
19
+ url: "jdbc:h2:./local/data/h2/fresh;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
20
+ user: sa
21
+ password: "sa"
22
+ atomikos:
23
+ log_base_dir: local/log/atomikos/fresh
@@ -11,11 +11,11 @@ quicksilver:
11
11
  # Keep the quotes around passwords: special characters (# : @ ...) then paste in as is.
12
12
  items:
13
13
  - code: metadata
14
- url: "jdbc:h2:./local/data/h2/database2;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
14
+ url: "jdbc:h2:./local/data/h2/h2;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
15
15
  user: sa
16
16
  password: "sa"
17
17
  - code: business
18
- url: "jdbc:h2:./local/data/h2/database2;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
18
+ url: "jdbc:h2:./local/data/h2/h2;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=false;MODE=MySQL"
19
19
  user: sa
20
20
  password: "sa"
21
21
  atomikos: