@harperfast/template-vue-studio 1.10.8 → 1.10.9

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.
@@ -2526,3 +2526,98 @@ loadEnv:
2526
2526
  - Because Harper is a single-process application, variables loaded onto `process.env` are shared across all components.
2527
2527
  - Without `override: true`, variables already set in the shell or container environment will not be overwritten by values in `.env` files.
2528
2528
  - `files` is the only required option; omitting it will produce an invalid configuration.
2529
+
2530
+ ### 4.7 Upgrading a Harper Application to v5
2531
+
2532
+ Instructions for the agent to follow when migrating an existing Harper application to version 5, addressing the breaking changes and adopting the recommended patterns.
2533
+
2534
+ #### When to Use
2535
+
2536
+ Apply this rule when upgrading a Harper application from v4.x (or earlier) to v5, or when code written against older APIs behaves differently after a v5 upgrade — for example a record that can no longer be mutated, a query that returns stale data, or a `spawn` call that now throws. Harper v5 introduces breaking changes; applications built on documented APIs need the updates below, while code relying on undocumented behavior or timing may need broader review.
2537
+
2538
+ #### How It Works
2539
+
2540
+ 1. **Adopt the `harper` package name**: HarperDB is now Harper, and the package was renamed. Install the open source edition with `npm i -g harper` and the pro edition with `npm i -g @harperfast/harper-pro`. Update application imports from `harperdb` to `harper`:
2541
+
2542
+ ```javascript
2543
+ import { tables } from 'harper';
2544
+ ```
2545
+
2546
+ 2. **Opt in to install scripts when required**: Harper now installs packages with `--ignore-scripts` to guard against accidental script execution, a common security risk. If an application genuinely needs install scripts to run (for example to build native binaries), pass the `allowInstallScripts` option when deploying.
2547
+
2548
+ 3. **Update `Table.get` return-value handling**: `Table.get` now returns a plain, frozen record object rather than an instance of the table class, so instance methods are no longer available on the result. The commonly used `wasLoadedFromSource()` method is gone; cache-vs-origin information now lives on the request `target` as `target.loadedFromSource`. Pass a `RequestTarget` to `Table.get` and read the flag from it. Because the record is frozen, create a copy instead of mutating it in place.
2549
+
2550
+ 4. **Account for automatic transaction context**: With RocksDB, transactions are fully supported by the storage engine, and Harper v5 uses asynchronous context tracking to carry the current transaction across calls automatically. A nested `Table.get` now reads within the current transaction's snapshot, so it will not observe newly written data until you commit. Access the context through `getContext()` and either commit the current transaction (`getContext().transaction.commit()`) or run the read inside a fresh `transaction(...)` to see the latest data. This matters most for code executing outside the context of a Harper request.
2551
+
2552
+ 5. **Register spawnable commands**: Spawning processes is now tightly controlled. `spawn`, `exec`, and `execFile` may only run executables listed in the `applications.allowedSpawnCommands` configuration, and each call must pass a `name` in its `options` so that only a single named process is started across Harper's multiple threads. Use a distinct `name` when you deliberately need a separate process.
2553
+
2554
+ 6. **Return Response-like objects to set headers**: If a REST method returns an object with a `headers` property, Harper uses it as the response headers.
2555
+
2556
+ 7. **Replace `blob.save()`**: The `blob.save()` method has been removed. Pass the `saveBeforeCommit` flag in the options to the `Blob` constructor instead.
2557
+
2558
+ 8. **Configure the VM module loader**: v5 loads application modules through Node.js's VM module API, giving each application its own module cache and an application-scoped `harper` module. All of this is controlled by the `applications` section of `harperdb-config.yaml`:
2559
+ - `moduleLoader` — `vm-current-context` (default), `vm`, `native`, or `compartment`. The default shares intrinsics with Harper for best compatibility; choose `vm` only if you need per-application intrinsics, and `native` to disable the VM loader entirely (restores pre-v5 loading, but per-app `logger`/`config` context is unavailable).
2560
+ - `lockdown` — `freeze-after-load` (default), `freeze`, `ses`, or `none`. Freezing intrinsics prevents prototype-pollution attacks; set `lockdown: none` only as a temporary workaround if a dependency mutates built-in prototypes.
2561
+ - `allowedDirectory` — `app` (default) restricts module loading to the application's own directory tree; set `any` if the app must load files from outside it in production.
2562
+ - `allowedBuiltinModules` — an optional allowlist restricting which Node.js built-ins the application may import (all are allowed if omitted).
2563
+ - `dependencyLoader` — `auto` (default), `app`, or `native`, controlling how npm dependencies are loaded through or around the VM loader.
2564
+
2565
+ #### Examples
2566
+
2567
+ **Updating `Table.get` and its cache check:**
2568
+
2569
+ ```javascript
2570
+ // Old (v4.x)
2571
+ const record = await Table.get(id);
2572
+ if (record.wasLoadedFromSource()) {
2573
+ // loaded from origin, not cache
2574
+ }
2575
+
2576
+ // New (v5)
2577
+ const target = new RequestTarget(); // passed in when overriding `get`
2578
+ target.id = id;
2579
+ const record = await Table.get(target);
2580
+ if (target.loadedFromSource) {
2581
+ // loaded from origin, not cache
2582
+ }
2583
+ ```
2584
+
2585
+ **Committing the transaction to read fresh data:**
2586
+
2587
+ ```javascript
2588
+ import { setTimeout as delay } from 'node:timers/promises';
2589
+ import { getContext, transaction } from 'harper';
2590
+
2591
+ class MyResource {
2592
+ static async get(target) {
2593
+ // The current transaction is a consistent snapshot; commit it to see updates.
2594
+ await getContext().transaction.commit();
2595
+ while ((await transaction(() => Table.get(target))).status !== 'ready') {
2596
+ delay(100);
2597
+ }
2598
+ return Table.get(target);
2599
+ }
2600
+ }
2601
+ ```
2602
+
2603
+ **Module loader and security configuration in `harperdb-config.yaml`:**
2604
+
2605
+ ```yaml
2606
+ applications:
2607
+ lockdown: freeze-after-load # default
2608
+ moduleLoader: vm-current-context # vm-current-context (default) | vm | native | compartment
2609
+ dependencyLoader: auto # auto (default) | app | native
2610
+ allowedDirectory: app # app (default) | any
2611
+ allowedSpawnCommands:
2612
+ - npm
2613
+ - node
2614
+ # allowedBuiltinModules: [] # if omitted, all Node.js built-ins are allowed
2615
+ ```
2616
+
2617
+ #### Recommended Changes
2618
+
2619
+ Beyond the required fixes above, Harper v5 encourages these patterns for new and migrated code:
2620
+
2621
+ - Implement endpoints with `static` methods on Resources/Tables, reading request information from the request `target` argument (or from `getContext()`).
2622
+ - Rely on automatic context propagation rather than threading context through every call manually; access it via `getContext()` exported from `harper`.
2623
+ - Access Harper functions and APIs through the `harper` package rather than through global variables.
@@ -83,6 +83,7 @@ See the concrete examples embedded in each rule subsection below (GraphQL schema
83
83
  - `serving-web-content` — How to serve static files and integrated Vite/React applications in Harper.
84
84
  - `logging` — Best practices for logging in Harper, including console capture, the granular logger interface, and programmatic log retrieval.
85
85
  - `load-env` — How to load environment variables from .env files into a Harper application using the loadEnv plugin.
86
+ - `v5-upgrade` — Breaking changes and recommended updates when migrating a Harper application to v5.
86
87
 
87
88
  <!-- END GENERATED INDEX -->
88
89
 
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: v5-upgrade
3
+ description: >-
4
+ Breaking changes and recommended updates when migrating a Harper application
5
+ to v5.
6
+ metadata:
7
+ mode: generate
8
+ sources:
9
+ - release-notes/v5-lincoln/v5-migration.md
10
+ sourceCommit: de2aaf1c759a7ff5b93e862ba704153e2a392fcb
11
+ inputHash: 80314689f3a7f42e
12
+ ---
13
+
14
+ # Upgrading a Harper Application to v5
15
+
16
+ Instructions for the agent to follow when migrating an existing Harper application to version 5, addressing the breaking changes and adopting the recommended patterns.
17
+
18
+ ## When to Use
19
+
20
+ Apply this rule when upgrading a Harper application from v4.x (or earlier) to v5, or when code written against older APIs behaves differently after a v5 upgrade — for example a record that can no longer be mutated, a query that returns stale data, or a `spawn` call that now throws. Harper v5 introduces breaking changes; applications built on documented APIs need the updates below, while code relying on undocumented behavior or timing may need broader review.
21
+
22
+ ## How It Works
23
+
24
+ 1. **Adopt the `harper` package name**: HarperDB is now Harper, and the package was renamed. Install the open source edition with `npm i -g harper` and the pro edition with `npm i -g @harperfast/harper-pro`. Update application imports from `harperdb` to `harper`:
25
+
26
+ ```javascript
27
+ import { tables } from 'harper';
28
+ ```
29
+
30
+ 2. **Opt in to install scripts when required**: Harper now installs packages with `--ignore-scripts` to guard against accidental script execution, a common security risk. If an application genuinely needs install scripts to run (for example to build native binaries), pass the `allowInstallScripts` option when deploying.
31
+
32
+ 3. **Update `Table.get` return-value handling**: `Table.get` now returns a plain, frozen record object rather than an instance of the table class, so instance methods are no longer available on the result. The commonly used `wasLoadedFromSource()` method is gone; cache-vs-origin information now lives on the request `target` as `target.loadedFromSource`. Pass a `RequestTarget` to `Table.get` and read the flag from it. Because the record is frozen, create a copy instead of mutating it in place.
33
+
34
+ 4. **Account for automatic transaction context**: With RocksDB, transactions are fully supported by the storage engine, and Harper v5 uses asynchronous context tracking to carry the current transaction across calls automatically. A nested `Table.get` now reads within the current transaction's snapshot, so it will not observe newly written data until you commit. Access the context through `getContext()` and either commit the current transaction (`getContext().transaction.commit()`) or run the read inside a fresh `transaction(...)` to see the latest data. This matters most for code executing outside the context of a Harper request.
35
+
36
+ 5. **Register spawnable commands**: Spawning processes is now tightly controlled. `spawn`, `exec`, and `execFile` may only run executables listed in the `applications.allowedSpawnCommands` configuration, and each call must pass a `name` in its `options` so that only a single named process is started across Harper's multiple threads. Use a distinct `name` when you deliberately need a separate process.
37
+
38
+ 6. **Return Response-like objects to set headers**: If a REST method returns an object with a `headers` property, Harper uses it as the response headers.
39
+
40
+ 7. **Replace `blob.save()`**: The `blob.save()` method has been removed. Pass the `saveBeforeCommit` flag in the options to the `Blob` constructor instead.
41
+
42
+ 8. **Configure the VM module loader**: v5 loads application modules through Node.js's VM module API, giving each application its own module cache and an application-scoped `harper` module. All of this is controlled by the `applications` section of `harperdb-config.yaml`:
43
+ - `moduleLoader` — `vm-current-context` (default), `vm`, `native`, or `compartment`. The default shares intrinsics with Harper for best compatibility; choose `vm` only if you need per-application intrinsics, and `native` to disable the VM loader entirely (restores pre-v5 loading, but per-app `logger`/`config` context is unavailable).
44
+ - `lockdown` — `freeze-after-load` (default), `freeze`, `ses`, or `none`. Freezing intrinsics prevents prototype-pollution attacks; set `lockdown: none` only as a temporary workaround if a dependency mutates built-in prototypes.
45
+ - `allowedDirectory` — `app` (default) restricts module loading to the application's own directory tree; set `any` if the app must load files from outside it in production.
46
+ - `allowedBuiltinModules` — an optional allowlist restricting which Node.js built-ins the application may import (all are allowed if omitted).
47
+ - `dependencyLoader` — `auto` (default), `app`, or `native`, controlling how npm dependencies are loaded through or around the VM loader.
48
+
49
+ ## Examples
50
+
51
+ **Updating `Table.get` and its cache check:**
52
+
53
+ ```javascript
54
+ // Old (v4.x)
55
+ const record = await Table.get(id);
56
+ if (record.wasLoadedFromSource()) {
57
+ // loaded from origin, not cache
58
+ }
59
+
60
+ // New (v5)
61
+ const target = new RequestTarget(); // passed in when overriding `get`
62
+ target.id = id;
63
+ const record = await Table.get(target);
64
+ if (target.loadedFromSource) {
65
+ // loaded from origin, not cache
66
+ }
67
+ ```
68
+
69
+ **Committing the transaction to read fresh data:**
70
+
71
+ ```javascript
72
+ import { setTimeout as delay } from 'node:timers/promises';
73
+ import { getContext, transaction } from 'harper';
74
+
75
+ class MyResource {
76
+ static async get(target) {
77
+ // The current transaction is a consistent snapshot; commit it to see updates.
78
+ await getContext().transaction.commit();
79
+ while ((await transaction(() => Table.get(target))).status !== 'ready') {
80
+ delay(100);
81
+ }
82
+ return Table.get(target);
83
+ }
84
+ }
85
+ ```
86
+
87
+ **Module loader and security configuration in `harperdb-config.yaml`:**
88
+
89
+ ```yaml
90
+ applications:
91
+ lockdown: freeze-after-load # default
92
+ moduleLoader: vm-current-context # vm-current-context (default) | vm | native | compartment
93
+ dependencyLoader: auto # auto (default) | app | native
94
+ allowedDirectory: app # app (default) | any
95
+ allowedSpawnCommands:
96
+ - npm
97
+ - node
98
+ # allowedBuiltinModules: [] # if omitted, all Node.js built-ins are allowed
99
+ ```
100
+
101
+ ## Recommended Changes
102
+
103
+ Beyond the required fixes above, Harper v5 encourages these patterns for new and migrated code:
104
+
105
+ - Implement endpoints with `static` methods on Resources/Tables, reading request information from the request `target` argument (or from `getContext()`).
106
+ - Rely on automatic context propagation rather than threading context through every call manually; access it via `getContext()` exported from `harper`.
107
+ - Access Harper functions and APIs through the `harper` package rather than through global variables.
@@ -402,3 +402,23 @@ rules:
402
402
  - 'process.env'
403
403
  - 'override'
404
404
  - 'config.yaml'
405
+
406
+ - rule: v5-upgrade
407
+ description: Breaking changes and recommended updates when migrating a Harper application to v5.
408
+ category: ops
409
+ priority: 4
410
+ order: 7
411
+ mode: generate
412
+ sources:
413
+ - path: release-notes/v5-lincoln/v5-migration.md
414
+ role: primary
415
+ must_cover:
416
+ - "from 'harper'"
417
+ - 'allowInstallScripts'
418
+ - 'loadedFromSource'
419
+ - 'getContext'
420
+ - 'allowedSpawnCommands'
421
+ - 'saveBeforeCommit'
422
+ - 'moduleLoader'
423
+ - 'lockdown'
424
+ - 'Table.get'
@@ -2526,3 +2526,98 @@ loadEnv:
2526
2526
  - Because Harper is a single-process application, variables loaded onto `process.env` are shared across all components.
2527
2527
  - Without `override: true`, variables already set in the shell or container environment will not be overwritten by values in `.env` files.
2528
2528
  - `files` is the only required option; omitting it will produce an invalid configuration.
2529
+
2530
+ ### 4.7 Upgrading a Harper Application to v5
2531
+
2532
+ Instructions for the agent to follow when migrating an existing Harper application to version 5, addressing the breaking changes and adopting the recommended patterns.
2533
+
2534
+ #### When to Use
2535
+
2536
+ Apply this rule when upgrading a Harper application from v4.x (or earlier) to v5, or when code written against older APIs behaves differently after a v5 upgrade — for example a record that can no longer be mutated, a query that returns stale data, or a `spawn` call that now throws. Harper v5 introduces breaking changes; applications built on documented APIs need the updates below, while code relying on undocumented behavior or timing may need broader review.
2537
+
2538
+ #### How It Works
2539
+
2540
+ 1. **Adopt the `harper` package name**: HarperDB is now Harper, and the package was renamed. Install the open source edition with `npm i -g harper` and the pro edition with `npm i -g @harperfast/harper-pro`. Update application imports from `harperdb` to `harper`:
2541
+
2542
+ ```javascript
2543
+ import { tables } from 'harper';
2544
+ ```
2545
+
2546
+ 2. **Opt in to install scripts when required**: Harper now installs packages with `--ignore-scripts` to guard against accidental script execution, a common security risk. If an application genuinely needs install scripts to run (for example to build native binaries), pass the `allowInstallScripts` option when deploying.
2547
+
2548
+ 3. **Update `Table.get` return-value handling**: `Table.get` now returns a plain, frozen record object rather than an instance of the table class, so instance methods are no longer available on the result. The commonly used `wasLoadedFromSource()` method is gone; cache-vs-origin information now lives on the request `target` as `target.loadedFromSource`. Pass a `RequestTarget` to `Table.get` and read the flag from it. Because the record is frozen, create a copy instead of mutating it in place.
2549
+
2550
+ 4. **Account for automatic transaction context**: With RocksDB, transactions are fully supported by the storage engine, and Harper v5 uses asynchronous context tracking to carry the current transaction across calls automatically. A nested `Table.get` now reads within the current transaction's snapshot, so it will not observe newly written data until you commit. Access the context through `getContext()` and either commit the current transaction (`getContext().transaction.commit()`) or run the read inside a fresh `transaction(...)` to see the latest data. This matters most for code executing outside the context of a Harper request.
2551
+
2552
+ 5. **Register spawnable commands**: Spawning processes is now tightly controlled. `spawn`, `exec`, and `execFile` may only run executables listed in the `applications.allowedSpawnCommands` configuration, and each call must pass a `name` in its `options` so that only a single named process is started across Harper's multiple threads. Use a distinct `name` when you deliberately need a separate process.
2553
+
2554
+ 6. **Return Response-like objects to set headers**: If a REST method returns an object with a `headers` property, Harper uses it as the response headers.
2555
+
2556
+ 7. **Replace `blob.save()`**: The `blob.save()` method has been removed. Pass the `saveBeforeCommit` flag in the options to the `Blob` constructor instead.
2557
+
2558
+ 8. **Configure the VM module loader**: v5 loads application modules through Node.js's VM module API, giving each application its own module cache and an application-scoped `harper` module. All of this is controlled by the `applications` section of `harperdb-config.yaml`:
2559
+ - `moduleLoader` — `vm-current-context` (default), `vm`, `native`, or `compartment`. The default shares intrinsics with Harper for best compatibility; choose `vm` only if you need per-application intrinsics, and `native` to disable the VM loader entirely (restores pre-v5 loading, but per-app `logger`/`config` context is unavailable).
2560
+ - `lockdown` — `freeze-after-load` (default), `freeze`, `ses`, or `none`. Freezing intrinsics prevents prototype-pollution attacks; set `lockdown: none` only as a temporary workaround if a dependency mutates built-in prototypes.
2561
+ - `allowedDirectory` — `app` (default) restricts module loading to the application's own directory tree; set `any` if the app must load files from outside it in production.
2562
+ - `allowedBuiltinModules` — an optional allowlist restricting which Node.js built-ins the application may import (all are allowed if omitted).
2563
+ - `dependencyLoader` — `auto` (default), `app`, or `native`, controlling how npm dependencies are loaded through or around the VM loader.
2564
+
2565
+ #### Examples
2566
+
2567
+ **Updating `Table.get` and its cache check:**
2568
+
2569
+ ```javascript
2570
+ // Old (v4.x)
2571
+ const record = await Table.get(id);
2572
+ if (record.wasLoadedFromSource()) {
2573
+ // loaded from origin, not cache
2574
+ }
2575
+
2576
+ // New (v5)
2577
+ const target = new RequestTarget(); // passed in when overriding `get`
2578
+ target.id = id;
2579
+ const record = await Table.get(target);
2580
+ if (target.loadedFromSource) {
2581
+ // loaded from origin, not cache
2582
+ }
2583
+ ```
2584
+
2585
+ **Committing the transaction to read fresh data:**
2586
+
2587
+ ```javascript
2588
+ import { setTimeout as delay } from 'node:timers/promises';
2589
+ import { getContext, transaction } from 'harper';
2590
+
2591
+ class MyResource {
2592
+ static async get(target) {
2593
+ // The current transaction is a consistent snapshot; commit it to see updates.
2594
+ await getContext().transaction.commit();
2595
+ while ((await transaction(() => Table.get(target))).status !== 'ready') {
2596
+ delay(100);
2597
+ }
2598
+ return Table.get(target);
2599
+ }
2600
+ }
2601
+ ```
2602
+
2603
+ **Module loader and security configuration in `harperdb-config.yaml`:**
2604
+
2605
+ ```yaml
2606
+ applications:
2607
+ lockdown: freeze-after-load # default
2608
+ moduleLoader: vm-current-context # vm-current-context (default) | vm | native | compartment
2609
+ dependencyLoader: auto # auto (default) | app | native
2610
+ allowedDirectory: app # app (default) | any
2611
+ allowedSpawnCommands:
2612
+ - npm
2613
+ - node
2614
+ # allowedBuiltinModules: [] # if omitted, all Node.js built-ins are allowed
2615
+ ```
2616
+
2617
+ #### Recommended Changes
2618
+
2619
+ Beyond the required fixes above, Harper v5 encourages these patterns for new and migrated code:
2620
+
2621
+ - Implement endpoints with `static` methods on Resources/Tables, reading request information from the request `target` argument (or from `getContext()`).
2622
+ - Rely on automatic context propagation rather than threading context through every call manually; access it via `getContext()` exported from `harper`.
2623
+ - Access Harper functions and APIs through the `harper` package rather than through global variables.
@@ -76,6 +76,7 @@ See the concrete examples embedded in each rule subsection below (GraphQL schema
76
76
  - `serving-web-content` — How to serve static files and integrated Vite/React applications in Harper.
77
77
  - `logging` — Best practices for logging in Harper, including console capture, the granular logger interface, and programmatic log retrieval.
78
78
  - `load-env` — How to load environment variables from .env files into a Harper application using the loadEnv plugin.
79
+ - `v5-upgrade` — Breaking changes and recommended updates when migrating a Harper application to v5.
79
80
 
80
81
  <!-- END GENERATED INDEX -->
81
82
 
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: v5-upgrade
3
+ description: >-
4
+ Breaking changes and recommended updates when migrating a Harper application
5
+ to v5.
6
+ metadata:
7
+ mode: generate
8
+ sources:
9
+ - release-notes/v5-lincoln/v5-migration.md
10
+ sourceCommit: de2aaf1c759a7ff5b93e862ba704153e2a392fcb
11
+ inputHash: 80314689f3a7f42e
12
+ ---
13
+
14
+ # Upgrading a Harper Application to v5
15
+
16
+ Instructions for the agent to follow when migrating an existing Harper application to version 5, addressing the breaking changes and adopting the recommended patterns.
17
+
18
+ ## When to Use
19
+
20
+ Apply this rule when upgrading a Harper application from v4.x (or earlier) to v5, or when code written against older APIs behaves differently after a v5 upgrade — for example a record that can no longer be mutated, a query that returns stale data, or a `spawn` call that now throws. Harper v5 introduces breaking changes; applications built on documented APIs need the updates below, while code relying on undocumented behavior or timing may need broader review.
21
+
22
+ ## How It Works
23
+
24
+ 1. **Adopt the `harper` package name**: HarperDB is now Harper, and the package was renamed. Install the open source edition with `npm i -g harper` and the pro edition with `npm i -g @harperfast/harper-pro`. Update application imports from `harperdb` to `harper`:
25
+
26
+ ```javascript
27
+ import { tables } from 'harper';
28
+ ```
29
+
30
+ 2. **Opt in to install scripts when required**: Harper now installs packages with `--ignore-scripts` to guard against accidental script execution, a common security risk. If an application genuinely needs install scripts to run (for example to build native binaries), pass the `allowInstallScripts` option when deploying.
31
+
32
+ 3. **Update `Table.get` return-value handling**: `Table.get` now returns a plain, frozen record object rather than an instance of the table class, so instance methods are no longer available on the result. The commonly used `wasLoadedFromSource()` method is gone; cache-vs-origin information now lives on the request `target` as `target.loadedFromSource`. Pass a `RequestTarget` to `Table.get` and read the flag from it. Because the record is frozen, create a copy instead of mutating it in place.
33
+
34
+ 4. **Account for automatic transaction context**: With RocksDB, transactions are fully supported by the storage engine, and Harper v5 uses asynchronous context tracking to carry the current transaction across calls automatically. A nested `Table.get` now reads within the current transaction's snapshot, so it will not observe newly written data until you commit. Access the context through `getContext()` and either commit the current transaction (`getContext().transaction.commit()`) or run the read inside a fresh `transaction(...)` to see the latest data. This matters most for code executing outside the context of a Harper request.
35
+
36
+ 5. **Register spawnable commands**: Spawning processes is now tightly controlled. `spawn`, `exec`, and `execFile` may only run executables listed in the `applications.allowedSpawnCommands` configuration, and each call must pass a `name` in its `options` so that only a single named process is started across Harper's multiple threads. Use a distinct `name` when you deliberately need a separate process.
37
+
38
+ 6. **Return Response-like objects to set headers**: If a REST method returns an object with a `headers` property, Harper uses it as the response headers.
39
+
40
+ 7. **Replace `blob.save()`**: The `blob.save()` method has been removed. Pass the `saveBeforeCommit` flag in the options to the `Blob` constructor instead.
41
+
42
+ 8. **Configure the VM module loader**: v5 loads application modules through Node.js's VM module API, giving each application its own module cache and an application-scoped `harper` module. All of this is controlled by the `applications` section of `harperdb-config.yaml`:
43
+ - `moduleLoader` — `vm-current-context` (default), `vm`, `native`, or `compartment`. The default shares intrinsics with Harper for best compatibility; choose `vm` only if you need per-application intrinsics, and `native` to disable the VM loader entirely (restores pre-v5 loading, but per-app `logger`/`config` context is unavailable).
44
+ - `lockdown` — `freeze-after-load` (default), `freeze`, `ses`, or `none`. Freezing intrinsics prevents prototype-pollution attacks; set `lockdown: none` only as a temporary workaround if a dependency mutates built-in prototypes.
45
+ - `allowedDirectory` — `app` (default) restricts module loading to the application's own directory tree; set `any` if the app must load files from outside it in production.
46
+ - `allowedBuiltinModules` — an optional allowlist restricting which Node.js built-ins the application may import (all are allowed if omitted).
47
+ - `dependencyLoader` — `auto` (default), `app`, or `native`, controlling how npm dependencies are loaded through or around the VM loader.
48
+
49
+ ## Examples
50
+
51
+ **Updating `Table.get` and its cache check:**
52
+
53
+ ```javascript
54
+ // Old (v4.x)
55
+ const record = await Table.get(id);
56
+ if (record.wasLoadedFromSource()) {
57
+ // loaded from origin, not cache
58
+ }
59
+
60
+ // New (v5)
61
+ const target = new RequestTarget(); // passed in when overriding `get`
62
+ target.id = id;
63
+ const record = await Table.get(target);
64
+ if (target.loadedFromSource) {
65
+ // loaded from origin, not cache
66
+ }
67
+ ```
68
+
69
+ **Committing the transaction to read fresh data:**
70
+
71
+ ```javascript
72
+ import { setTimeout as delay } from 'node:timers/promises';
73
+ import { getContext, transaction } from 'harper';
74
+
75
+ class MyResource {
76
+ static async get(target) {
77
+ // The current transaction is a consistent snapshot; commit it to see updates.
78
+ await getContext().transaction.commit();
79
+ while ((await transaction(() => Table.get(target))).status !== 'ready') {
80
+ delay(100);
81
+ }
82
+ return Table.get(target);
83
+ }
84
+ }
85
+ ```
86
+
87
+ **Module loader and security configuration in `harperdb-config.yaml`:**
88
+
89
+ ```yaml
90
+ applications:
91
+ lockdown: freeze-after-load # default
92
+ moduleLoader: vm-current-context # vm-current-context (default) | vm | native | compartment
93
+ dependencyLoader: auto # auto (default) | app | native
94
+ allowedDirectory: app # app (default) | any
95
+ allowedSpawnCommands:
96
+ - npm
97
+ - node
98
+ # allowedBuiltinModules: [] # if omitted, all Node.js built-ins are allowed
99
+ ```
100
+
101
+ ## Recommended Changes
102
+
103
+ Beyond the required fixes above, Harper v5 encourages these patterns for new and migrated code:
104
+
105
+ - Implement endpoints with `static` methods on Resources/Tables, reading request information from the request `target` argument (or from `getContext()`).
106
+ - Rely on automatic context propagation rather than threading context through every call manually; access it via `getContext()` exported from `harper`.
107
+ - Access Harper functions and APIs through the `harper` package rather than through global variables.
@@ -402,3 +402,23 @@ rules:
402
402
  - 'process.env'
403
403
  - 'override'
404
404
  - 'config.yaml'
405
+
406
+ - rule: v5-upgrade
407
+ description: Breaking changes and recommended updates when migrating a Harper application to v5.
408
+ category: ops
409
+ priority: 4
410
+ order: 7
411
+ mode: generate
412
+ sources:
413
+ - path: release-notes/v5-lincoln/v5-migration.md
414
+ role: primary
415
+ must_cover:
416
+ - "from 'harper'"
417
+ - 'allowInstallScripts'
418
+ - 'loadedFromSource'
419
+ - 'getContext'
420
+ - 'allowedSpawnCommands'
421
+ - 'saveBeforeCommit'
422
+ - 'moduleLoader'
423
+ - 'lockdown'
424
+ - 'Table.get'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harperfast/template-vue-studio",
3
- "version": "1.10.8",
3
+ "version": "1.10.9",
4
4
  "type": "module",
5
5
  "repository": "github:HarperFast/create-harper",
6
6
  "scripts": {},
package/skills-lock.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "source": "harperfast/skills",
6
6
  "sourceType": "github",
7
7
  "skillPath": "harper-best-practices/SKILL.md",
8
- "computedHash": "142388c071178e7ae811bfd4f6241e85aef3f715dbfb0ceea1b75e8f370d8080"
8
+ "computedHash": "2293a12dd5c59704c4d6ea0a6c54314a9c31af2d06015ddb63dcb6dbee5f8b79"
9
9
  }
10
10
  }
11
11
  }