@harperfast/template-vue-ts-studio 1.9.1 → 1.10.0
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/.agents/skills/harper-best-practices/AGENTS.md +770 -254
- package/.agents/skills/harper-best-practices/rules/caching.md +68 -62
- package/.agents/skills/harper-best-practices/rules/custom-resources.md +106 -23
- package/.agents/skills/harper-best-practices/rules/defining-relationships.md +152 -22
- package/.agents/skills/harper-best-practices/rules/extending-tables.md +90 -21
- package/.agents/skills/harper-best-practices/rules/handling-binary-data.md +103 -23
- package/.agents/skills/harper-best-practices/rules/programmatic-table-requests.md +51 -7
- package/.agents/skills/harper-best-practices/rules/schema-design-tooling.md +87 -64
- package/.agents/skills/harper-best-practices/rules/using-blob-datatype.md +96 -16
- package/.agents/skills/harper-best-practices/rules/vector-indexing.md +59 -29
- package/.agents/skills/harper-best-practices/rules.manifest.yaml +83 -6
- package/agent/skills/harper-best-practices/AGENTS.md +770 -254
- package/agent/skills/harper-best-practices/rules/caching.md +68 -62
- package/agent/skills/harper-best-practices/rules/custom-resources.md +106 -23
- package/agent/skills/harper-best-practices/rules/defining-relationships.md +152 -22
- package/agent/skills/harper-best-practices/rules/extending-tables.md +90 -21
- package/agent/skills/harper-best-practices/rules/handling-binary-data.md +103 -23
- package/agent/skills/harper-best-practices/rules/programmatic-table-requests.md +51 -7
- package/agent/skills/harper-best-practices/rules/schema-design-tooling.md +87 -64
- package/agent/skills/harper-best-practices/rules/using-blob-datatype.md +96 -16
- package/agent/skills/harper-best-practices/rules/vector-indexing.md +59 -29
- package/agent/skills/harper-best-practices/rules.manifest.yaml +83 -6
- package/package.json +1 -1
- package/skills-lock.json +1 -1
|
@@ -2,37 +2,117 @@
|
|
|
2
2
|
name: using-blob-datatype
|
|
3
3
|
description: How to use the Blob data type for efficient binary storage in Harper.
|
|
4
4
|
metadata:
|
|
5
|
-
mode:
|
|
5
|
+
mode: generate
|
|
6
|
+
sources:
|
|
7
|
+
- reference/v5/database/schema.md#Blob Type
|
|
8
|
+
- reference/v5/database/api.md#Streaming
|
|
9
|
+
- reference/v5/database/api.md#`BlobOptions`
|
|
10
|
+
- reference/v5/database/api.md#Blob Coercion
|
|
11
|
+
sourceCommit: 4fe4c9c95e0974eaa77032f6f10e36fbd8ec64ac
|
|
12
|
+
inputHash: 71a3e738ebf87fa4
|
|
6
13
|
---
|
|
7
14
|
|
|
8
|
-
# Using Blob
|
|
15
|
+
# Using the Blob Data Type
|
|
9
16
|
|
|
10
|
-
Instructions for the agent to follow when
|
|
17
|
+
Instructions for the agent to follow when storing and retrieving large binary content using Harper's `Blob` data type.
|
|
11
18
|
|
|
12
19
|
## When to Use
|
|
13
20
|
|
|
14
|
-
|
|
21
|
+
Apply this rule when a schema field needs to store large binary content such as images, video, audio, or large HTML — typically content larger than 20KB. Use `Blob` instead of `Bytes` when you need streaming support or want to avoid loading the entire value into memory. See [handling-binary-data.md](handling-binary-data.md) for broader binary data guidance.
|
|
15
22
|
|
|
16
23
|
## How It Works
|
|
17
24
|
|
|
18
|
-
1. **
|
|
25
|
+
1. **Declare a `Blob` field in your schema**: Add a field typed as `Blob` to a `@table` type.
|
|
26
|
+
|
|
19
27
|
```graphql
|
|
20
28
|
type MyTable @table {
|
|
21
|
-
id:
|
|
29
|
+
id: Any! @primaryKey
|
|
22
30
|
data: Blob
|
|
23
31
|
}
|
|
24
32
|
```
|
|
25
|
-
|
|
33
|
+
|
|
34
|
+
2. **Create a blob with `createBlob()`**: Pass a buffer, string, or stream as the first argument. Pass a `BlobOptions` object as the second argument to configure behavior.
|
|
35
|
+
|
|
36
|
+
```javascript
|
|
37
|
+
let blob = createBlob(largeBuffer);
|
|
38
|
+
await MyTable.put({ id: 'my-record', data: blob });
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
3. **Read blob data using standard Web API methods**: The `Blob` type implements the Web API `Blob` interface. Use `.bytes()`, `.text()`, `.arrayBuffer()`, `.stream()`, or `.slice()` to access content.
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
let record = await MyTable.get('my-record');
|
|
45
|
+
let buffer = await record.data.bytes(); // ArrayBuffer
|
|
46
|
+
let text = await record.data.text(); // string
|
|
47
|
+
let stream = record.data.stream(); // ReadableStream
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
4. **Use `saveBeforeCommit` for ACID-compliant writes**: By default, blobs are not ACID-compliant — a record can reference a blob before it is fully written. Set `saveBeforeCommit: true` to wait for the full write before the transaction commits.
|
|
51
|
+
|
|
26
52
|
```javascript
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
53
|
+
let blob = createBlob(stream, { saveBeforeCommit: true });
|
|
54
|
+
await MyTable.put({ id: 'my-record', data: blob });
|
|
55
|
+
// put() resolves only after blob is fully written and record is committed
|
|
30
56
|
```
|
|
31
|
-
|
|
32
|
-
|
|
57
|
+
|
|
58
|
+
5. **Register an error handler when returning a blob via REST**: Interrupted streams must be handled explicitly to avoid stale records.
|
|
59
|
+
|
|
33
60
|
```javascript
|
|
34
|
-
|
|
35
|
-
|
|
61
|
+
export class MyEndpoint extends MyTable {
|
|
62
|
+
static async get(target) {
|
|
63
|
+
const record = super.get(target);
|
|
64
|
+
let blob = record.data;
|
|
65
|
+
blob.on('error', () => {
|
|
66
|
+
MyTable.invalidate(target);
|
|
67
|
+
});
|
|
68
|
+
return { status: 200, headers: {}, body: blob };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
36
71
|
```
|
|
37
|
-
|
|
38
|
-
6. **
|
|
72
|
+
|
|
73
|
+
6. **Rely on automatic coercion where applicable**: When a field is typed as `Blob` in the schema, any string or buffer assigned via `put`, `patch`, or `publish` is automatically coerced to a `Blob`. Manual `createBlob()` calls are not required for plain JSON HTTP bodies or MQTT messages in most cases.
|
|
74
|
+
|
|
75
|
+
### `BlobOptions` Reference
|
|
76
|
+
|
|
77
|
+
| Option | Type | Default | Description |
|
|
78
|
+
| ------------------ | --------- | ----------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
79
|
+
| `type` | `string` | `undefined` | MIME type to associate with the blob (e.g., `image/jpeg`). Readable via `blob.type` and used when serving HTTP. |
|
|
80
|
+
| `size` | `number` | `undefined` | Size of the data in bytes, if known ahead of time. Otherwise inferred from a buffer or determined as a stream completes. |
|
|
81
|
+
| `saveBeforeCommit` | `boolean` | `false` | Wait for the blob to be fully written before committing the transaction. |
|
|
82
|
+
| `compress` | `boolean` | `false` | Compress the stored data with deflate. |
|
|
83
|
+
| `flush` | `boolean` | `false` | Flush the file to disk after writing, before the `createBlob` promise chain resolves. |
|
|
84
|
+
|
|
85
|
+
## Examples
|
|
86
|
+
|
|
87
|
+
**Store an image with a MIME type:**
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
let blob = createBlob(imageBuffer, { type: 'image/jpeg' });
|
|
91
|
+
await Photo.put({ id, data: blob });
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Stream large media with low latency:**
|
|
95
|
+
|
|
96
|
+
```javascript
|
|
97
|
+
let blob = createBlob(incomingStream);
|
|
98
|
+
// blob exists, but data is still streaming to storage
|
|
99
|
+
await MyTable.put({ id: 'my-record', data: blob });
|
|
100
|
+
|
|
101
|
+
let record = await MyTable.get('my-record');
|
|
102
|
+
// blob data is accessible as it arrives
|
|
103
|
+
let outgoingStream = record.data.stream();
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Guaranteed write before commit:**
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
let blob = createBlob(stream, { saveBeforeCommit: true });
|
|
110
|
+
await MyTable.put({ id: 'my-record', data: blob });
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Notes
|
|
114
|
+
|
|
115
|
+
- `Blob` stores data separately from the record; `Bytes` does not. Prefer `Blob` for content larger than 20KB.
|
|
116
|
+
- All standard Web API `Blob` methods are available: `.bytes()`, `.text()`, `.arrayBuffer()`, `.stream()`, `.slice()`.
|
|
117
|
+
- Blobs are **not** ACID-compliant by default when created from a stream. Use `saveBeforeCommit: true` to enforce transactional consistency.
|
|
118
|
+
- Always attach an `error` handler on blobs returned as HTTP response bodies to handle interrupted streams.
|
|
@@ -5,21 +5,21 @@ metadata:
|
|
|
5
5
|
mode: generate
|
|
6
6
|
sources:
|
|
7
7
|
- reference/v5/database/schema.md#Vector Indexing
|
|
8
|
-
sourceCommit:
|
|
9
|
-
inputHash:
|
|
8
|
+
sourceCommit: 4fe4c9c95e0974eaa77032f6f10e36fbd8ec64ac
|
|
9
|
+
inputHash: d90b1b74597d08a6
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Vector Indexing
|
|
13
13
|
|
|
14
|
-
Instructions for the agent to
|
|
14
|
+
Instructions for the agent to enable HNSW vector indexes on table fields and query them for similarity search in Harper.
|
|
15
15
|
|
|
16
16
|
## When to Use
|
|
17
17
|
|
|
18
|
-
Apply this rule when adding a vector
|
|
18
|
+
Apply this rule when adding a vector similarity search capability to a Harper table — for example, storing text embeddings and querying for nearest neighbors, filtering by distance threshold, or tuning index construction and search parameters. Use it alongside [adding-tables-with-schemas.md](adding-tables-with-schemas.md) when defining the schema that hosts the vector field.
|
|
19
19
|
|
|
20
20
|
## How It Works
|
|
21
21
|
|
|
22
|
-
1. **Declare the vector index on a
|
|
22
|
+
1. **Declare the vector index on a field**: Add `@indexed(type: "HNSW")` to a `[Float]` field inside a `@table` type. This creates an HNSW (Hierarchical Navigable Small World) index for approximate nearest-neighbor search.
|
|
23
23
|
|
|
24
24
|
```graphql
|
|
25
25
|
type Document @table {
|
|
@@ -28,7 +28,7 @@ Apply this rule when adding a vector index to a Harper table schema or writing s
|
|
|
28
28
|
}
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
2. **Query by nearest neighbors using `sort`**: Call
|
|
31
|
+
2. **Query by nearest neighbors using `sort`**: Call `.search()` with a `sort` descriptor that specifies the indexed `attribute` and a `target` vector. Use `limit` to cap results.
|
|
32
32
|
|
|
33
33
|
```javascript
|
|
34
34
|
let results = Document.search({
|
|
@@ -47,7 +47,7 @@ Apply this rule when adding a vector index to a Harper table schema or writing s
|
|
|
47
47
|
});
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
4. **Filter by distance threshold**: To return only records within a similarity cutoff (without ranking), place `target` directly on the condition alongside `comparator` and `value`.
|
|
50
|
+
4. **Filter by distance threshold**: To return only records within a similarity cutoff (without ranking), place `target` directly on the condition alongside `comparator` and `value`. This bounds result quality rather than ranking by similarity.
|
|
51
51
|
|
|
52
52
|
```javascript
|
|
53
53
|
let results = Document.search({
|
|
@@ -60,7 +60,7 @@ Apply this rule when adding a vector index to a Harper table schema or writing s
|
|
|
60
60
|
});
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
5. **Include computed distance in results**: Use the special `$distance` field in `select` to return the distance from the target vector.
|
|
63
|
+
5. **Include computed distance in results**: Use the special `$distance` field in `select` to return the distance from the target vector. Available in both `sort`-based and threshold-based queries.
|
|
64
64
|
|
|
65
65
|
```javascript
|
|
66
66
|
let results = Document.search({
|
|
@@ -70,43 +70,59 @@ Apply this rule when adding a vector index to a Harper table schema or writing s
|
|
|
70
70
|
});
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
6. **Tune
|
|
73
|
+
6. **Tune per-query search options**: Pass `distance` and `ef` directly on the `sort` descriptor to override index defaults for a single query.
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
75
|
+
```javascript
|
|
76
|
+
let results = Document.search({
|
|
77
|
+
sort: { attribute: 'textEmbeddings', target: searchVector, distance: 'dotProduct', ef: 200 },
|
|
78
|
+
limit: 5,
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- `distance` — overrides the distance function for this query: `"cosine"`, `"euclidean"`, or `"dotProduct"`.
|
|
83
|
+
- `ef` — overrides the search exploration budget. Higher values improve recall at the cost of latency.
|
|
84
|
+
|
|
85
|
+
7. **Configure HNSW index parameters**: Pass parameters directly in the `@indexed` directive. Structural parameters (`distance`, `M`, `efConstruction`, `quantization`) trigger an index rebuild when changed; `efConstructionSearch` does not.
|
|
86
|
+
|
|
87
|
+
```graphql
|
|
88
|
+
type Document @table {
|
|
89
|
+
id: Long @primaryKey
|
|
90
|
+
textEmbeddings: [Float]
|
|
91
|
+
@indexed(type: "HNSW", distance: "euclidean", optimizeRouting: 0, efConstructionSearch: 100)
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
8. **Enable vector quantization**: Use `quantization: "int8"` to store vectors as 8-bit integers, reducing index size and memory usage. Harper re-ranks nearest-neighbor `sort` results against full-precision vectors automatically.
|
|
96
|
+
|
|
97
|
+
```graphql
|
|
98
|
+
type Document @table {
|
|
99
|
+
id: Long @primaryKey
|
|
100
|
+
textEmbeddings: [Float] @indexed(type: "HNSW", quantization: "int8")
|
|
101
|
+
}
|
|
102
|
+
```
|
|
83
103
|
|
|
84
104
|
## Examples
|
|
85
105
|
|
|
86
|
-
|
|
106
|
+
Full schema with custom HNSW parameters and a nearest-neighbor query with distance output:
|
|
87
107
|
|
|
88
108
|
```graphql
|
|
89
109
|
type Document @table {
|
|
90
110
|
id: Long @primaryKey
|
|
91
111
|
textEmbeddings: [Float]
|
|
92
|
-
@indexed(type: "HNSW", distance: "euclidean", optimizeRouting: 0,
|
|
112
|
+
@indexed(type: "HNSW", distance: "euclidean", optimizeRouting: 0, efConstructionSearch: 100)
|
|
93
113
|
}
|
|
94
114
|
```
|
|
95
115
|
|
|
96
|
-
**Nearest-neighbor search with distance score:**
|
|
97
|
-
|
|
98
116
|
```javascript
|
|
117
|
+
// Nearest-neighbor search with distance scores
|
|
99
118
|
let results = Document.search({
|
|
100
119
|
select: ['name', '$distance'],
|
|
101
120
|
sort: { attribute: 'textEmbeddings', target: searchVector },
|
|
102
121
|
limit: 5,
|
|
103
122
|
});
|
|
104
|
-
```
|
|
105
123
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
```javascript
|
|
109
|
-
let results = Document.search({
|
|
124
|
+
// Distance-threshold query (no ranking)
|
|
125
|
+
let closeMatches = Document.search({
|
|
110
126
|
conditions: {
|
|
111
127
|
attribute: 'textEmbeddings',
|
|
112
128
|
comparator: 'lt',
|
|
@@ -118,7 +134,21 @@ let results = Document.search({
|
|
|
118
134
|
|
|
119
135
|
## Notes
|
|
120
136
|
|
|
121
|
-
|
|
122
|
-
|
|
137
|
+
### HNSW Parameters
|
|
138
|
+
|
|
139
|
+
| Parameter | Default | Description |
|
|
140
|
+
| ---------------------- | ----------------- | ------------------------------------------------------------------------------------------------------ |
|
|
141
|
+
| `distance` | `"cosine"` | Distance function: `"cosine"`, `"euclidean"`, or `"dotProduct"` |
|
|
142
|
+
| `efConstruction` | `100` | Max nodes explored during index construction. Higher = better recall, lower = better performance |
|
|
143
|
+
| `M` | `16` | Preferred connections per graph layer. Higher = more space, better recall for high-dimensional data |
|
|
144
|
+
| `optimizeRouting` | `0.5` | Heuristic aggressiveness for omitting redundant connections (0 = off, 1 = most aggressive) |
|
|
145
|
+
| `mL` | computed from `M` | Normalization factor for level generation |
|
|
146
|
+
| `efConstructionSearch` | auto-scaled | Max nodes explored during search. When unset, auto-scales with index size; setting it fixes the budget |
|
|
147
|
+
| `quantization` | — | `"int8"` stores vectors quantized to int8 |
|
|
148
|
+
|
|
149
|
+
- The `distance` option on a per-query `sort` descriptor accepts `"cosine"`, `"euclidean"`, or `"dotProduct"`.
|
|
150
|
+
- When no `ef` is passed and `efConstructionSearch` (or `efConstruction`) is not explicitly set on the index, the search budget auto-scales with index size.
|
|
151
|
+
- `efConstruction` seeds the initial value of `efConstructionSearch`; setting either one fixes the search budget.
|
|
152
|
+
- The correct parameter name is `efConstructionSearch` (not `efSearchConstruction`).
|
|
123
153
|
- `$distance` is available in both `sort`-based ranking and `conditions`-based threshold queries.
|
|
124
|
-
-
|
|
154
|
+
- For `quantization: "int8"`, distance-threshold (`lt`/`le`) queries filter on approximate distance; `sort` queries re-rank against full-precision vectors.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#
|
|
3
3
|
# Declarative source of truth for rule taxonomy, sources, and generation mode.
|
|
4
4
|
# Owned by humans; the generator reads this file and writes derived artifacts
|
|
5
|
-
# (rule bodies, AGENTS.md). See docs/plans/docs-driven-skills.md for the
|
|
5
|
+
# (rule bodies, AGENTS.md). See docs/plans-archive/docs-driven-skills.md for the
|
|
6
6
|
# full schema definition and Manifest ↔ frontmatter reconciliation semantics.
|
|
7
7
|
#
|
|
8
8
|
# Phase 2 flipped vector-indexing to mode: generate.
|
|
@@ -53,7 +53,20 @@ rules:
|
|
|
53
53
|
category: schema
|
|
54
54
|
priority: 1
|
|
55
55
|
order: 3
|
|
56
|
-
mode:
|
|
56
|
+
mode: generate
|
|
57
|
+
sources:
|
|
58
|
+
- path: reference/v5/database/schema.md
|
|
59
|
+
section: 'Relationships'
|
|
60
|
+
role: primary
|
|
61
|
+
- path: reference/v5/rest/querying.md
|
|
62
|
+
section: 'Relationships and Joins'
|
|
63
|
+
role: supplemental
|
|
64
|
+
must_cover:
|
|
65
|
+
- '@relationship'
|
|
66
|
+
- 'from'
|
|
67
|
+
- 'to'
|
|
68
|
+
- 'one-to-many'
|
|
69
|
+
- 'many-to-one'
|
|
57
70
|
|
|
58
71
|
- rule: vector-indexing
|
|
59
72
|
description: How to enable and query vector indexes for similarity search in Harper.
|
|
@@ -79,14 +92,51 @@ rules:
|
|
|
79
92
|
category: schema
|
|
80
93
|
priority: 1
|
|
81
94
|
order: 5
|
|
82
|
-
mode:
|
|
95
|
+
mode: generate
|
|
96
|
+
sources:
|
|
97
|
+
- path: reference/v5/database/schema.md
|
|
98
|
+
section: 'Blob Type'
|
|
99
|
+
role: primary
|
|
100
|
+
- path: reference/v5/database/api.md
|
|
101
|
+
section: 'Streaming'
|
|
102
|
+
role: supplemental
|
|
103
|
+
- path: reference/v5/database/api.md
|
|
104
|
+
section: '`BlobOptions`'
|
|
105
|
+
role: supplemental
|
|
106
|
+
- path: reference/v5/database/api.md
|
|
107
|
+
section: 'Blob Coercion'
|
|
108
|
+
role: supplemental
|
|
109
|
+
must_cover:
|
|
110
|
+
- 'Blob'
|
|
111
|
+
- 'createBlob'
|
|
112
|
+
- 'saveBeforeCommit'
|
|
113
|
+
- '.bytes()'
|
|
114
|
+
cross_links:
|
|
115
|
+
- handling-binary-data
|
|
83
116
|
|
|
84
117
|
- rule: handling-binary-data
|
|
85
118
|
description: How to store and serve binary data like images or audio in Harper.
|
|
86
119
|
category: schema
|
|
87
120
|
priority: 1
|
|
88
121
|
order: 6
|
|
89
|
-
mode:
|
|
122
|
+
mode: generate
|
|
123
|
+
sources:
|
|
124
|
+
- path: reference/v5/database/api.md
|
|
125
|
+
section: 'Accepting Binary in JSON Requests'
|
|
126
|
+
role: primary
|
|
127
|
+
- path: reference/v5/database/api.md
|
|
128
|
+
section: 'Serving Binary from a Resource'
|
|
129
|
+
role: primary
|
|
130
|
+
- path: reference/v5/rest/content-types.md
|
|
131
|
+
section: 'Storing Arbitrary Content Types'
|
|
132
|
+
role: supplemental
|
|
133
|
+
must_cover:
|
|
134
|
+
- 'createBlob'
|
|
135
|
+
- 'Content-Type'
|
|
136
|
+
- 'application/octet-stream'
|
|
137
|
+
- 'base64'
|
|
138
|
+
cross_links:
|
|
139
|
+
- using-blob-datatype
|
|
90
140
|
|
|
91
141
|
# ===========================================================================
|
|
92
142
|
# API & Communication (priority 2 — HIGH)
|
|
@@ -176,14 +226,41 @@ rules:
|
|
|
176
226
|
category: logic
|
|
177
227
|
priority: 3
|
|
178
228
|
order: 1
|
|
179
|
-
mode:
|
|
229
|
+
mode: generate
|
|
230
|
+
sources:
|
|
231
|
+
- path: reference/v5/resources/overview.md
|
|
232
|
+
section: 'Custom External Data Source'
|
|
233
|
+
role: primary
|
|
234
|
+
- path: reference/v5/resources/overview.md
|
|
235
|
+
section: 'Exporting Resources as Endpoints'
|
|
236
|
+
role: primary
|
|
237
|
+
- path: reference/v5/components/javascript-environment.md
|
|
238
|
+
section: 'Module Loading'
|
|
239
|
+
role: supplemental
|
|
240
|
+
must_cover:
|
|
241
|
+
- 'extends Resource'
|
|
242
|
+
- 'export class'
|
|
243
|
+
- 'server.resources.set('
|
|
244
|
+
- 'static'
|
|
180
245
|
|
|
181
246
|
- rule: extending-tables
|
|
182
247
|
description: How to add custom logic to automatically generated table resources in Harper.
|
|
183
248
|
category: logic
|
|
184
249
|
priority: 3
|
|
185
250
|
order: 2
|
|
186
|
-
mode:
|
|
251
|
+
mode: generate
|
|
252
|
+
sources:
|
|
253
|
+
- path: reference/v5/resources/overview.md
|
|
254
|
+
section: 'Extending a Table'
|
|
255
|
+
role: primary
|
|
256
|
+
- path: reference/v5/resources/resource-api.md
|
|
257
|
+
section: 'Throwing Errors'
|
|
258
|
+
role: supplemental
|
|
259
|
+
must_cover:
|
|
260
|
+
- 'extends tables.'
|
|
261
|
+
- 'super.'
|
|
262
|
+
- '@export'
|
|
263
|
+
- 'statusCode'
|
|
187
264
|
|
|
188
265
|
- rule: programmatic-table-requests
|
|
189
266
|
description: How to interact with Harper tables programmatically using the `tables` object.
|