@jaypie/mcp 0.8.30 → 0.8.31
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.
|
@@ -9,7 +9,7 @@ import { gt } from 'semver';
|
|
|
9
9
|
/**
|
|
10
10
|
* Docs Suite - Documentation services (skill, version, release_notes)
|
|
11
11
|
*/
|
|
12
|
-
const BUILD_VERSION_STRING = "@jaypie/mcp@0.8.
|
|
12
|
+
const BUILD_VERSION_STRING = "@jaypie/mcp@0.8.31#0d902410"
|
|
13
13
|
;
|
|
14
14
|
const __filename$1 = fileURLToPath(import.meta.url);
|
|
15
15
|
const __dirname$1 = path.dirname(__filename$1);
|
package/package.json
CHANGED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 0.6.0
|
|
3
|
+
date: 2026-04-13
|
|
4
|
+
summary: Replace `putEntity` with `createEntity` (conditional `attribute_not_exists(id)`) to remove the silent-clobber footgun
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Breaking changes
|
|
8
|
+
|
|
9
|
+
- **Removed `putEntity`.** The unconditional `PutCommand` it issued was a
|
|
10
|
+
silent-clobber footgun: callers using it as "ensure exists" overwrote
|
|
11
|
+
embedded fields (e.g., `messages: []`) on every call. `putEntity` was also
|
|
12
|
+
semantically identical to `updateEntity`, so it was dead weight as well as
|
|
13
|
+
a trap. Migrate based on intent:
|
|
14
|
+
- "I want this row to exist, do nothing if it already does" → `createEntity`
|
|
15
|
+
- "I want this row to be exactly these values, replacing any prior state" → `updateEntity`
|
|
16
|
+
|
|
17
|
+
## New
|
|
18
|
+
|
|
19
|
+
- **`createEntity({ entity })`**: writes with
|
|
20
|
+
`ConditionExpression: "attribute_not_exists(id)"`. On
|
|
21
|
+
`ConditionalCheckFailedException`, returns `null` instead of throwing.
|
|
22
|
+
Other errors propagate normally. Return type is `StorableEntity | null`.
|
|
23
|
+
|
|
24
|
+
## MCP
|
|
25
|
+
|
|
26
|
+
- The `dynamodb_put` tool is renamed to `dynamodb_create` and now wraps
|
|
27
|
+
`createEntity`.
|
|
28
|
+
|
|
29
|
+
## Migration
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
// Before
|
|
33
|
+
await putEntity({ entity }); // silently overwrote on second call
|
|
34
|
+
|
|
35
|
+
// After — pick the verb that matches intent
|
|
36
|
+
await createEntity({ entity }); // ensure exists; null if id taken
|
|
37
|
+
await updateEntity({ entity }); // overwrite (was putEntity's actual behavior)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Internal callers in `seedExport` (`seedEntityIfNotExists`, `seedEntities`)
|
|
41
|
+
were migrated: the create paths use `createEntity`; the `replace: true`
|
|
42
|
+
path uses `updateEntity`.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 0.3.1
|
|
3
|
+
date: 2026-04-13
|
|
4
|
+
summary: FabricData create service uses `createEntity` (was `putEntity`) from `@jaypie/dynamodb` 0.6.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- `createCreateService` (the POST `/{model}` handler in FabricData) now
|
|
10
|
+
imports `createEntity` instead of `putEntity`. Behavior is unchanged in
|
|
11
|
+
practice: the create service generates a fresh UUID for `id`, so the new
|
|
12
|
+
conditional write never collides; if a caller supplies a colliding `id`
|
|
13
|
+
via a custom transform, the service now returns `null` instead of
|
|
14
|
+
silently overwriting.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 0.8.31
|
|
3
|
+
date: 2026-04-13
|
|
4
|
+
summary: Update dynamodb skill docs and pull `@jaypie/dynamodb` 0.6.0 (`createEntity` replaces `putEntity`)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- `dynamodb` skill updated: `putEntity` examples and table entry replaced
|
|
10
|
+
with `createEntity`.
|
|
11
|
+
- Pulls `@jaypie/dynamodb` 0.6.0 with renamed MCP tool `dynamodb_create`
|
|
12
|
+
(was `dynamodb_put`).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.33
|
|
3
|
+
date: 2026-04-13
|
|
4
|
+
summary: Replace `putEntity` mock with `createEntity` to match `@jaypie/dynamodb` 0.6.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Changes
|
|
8
|
+
|
|
9
|
+
- Removed `putEntity` mock; added `createEntity` mock that returns the
|
|
10
|
+
indexed entity (or `null` to simulate `ConditionalCheckFailedException`,
|
|
11
|
+
via `mockResolvedValueOnce(null)`).
|
package/skills/dynamodb.md
CHANGED
|
@@ -33,7 +33,7 @@ The runtime package provides entity operations, GSI-based queries, key builders,
|
|
|
33
33
|
import {
|
|
34
34
|
APEX,
|
|
35
35
|
initClient,
|
|
36
|
-
|
|
36
|
+
createEntity,
|
|
37
37
|
getEntity,
|
|
38
38
|
deleteEntity,
|
|
39
39
|
queryByScope,
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
Or through the main package:
|
|
45
45
|
|
|
46
46
|
```typescript
|
|
47
|
-
import { APEX, initClient,
|
|
47
|
+
import { APEX, initClient, createEntity, queryByScope } from "jaypie";
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
### Client Initialization
|
|
@@ -121,10 +121,10 @@ interface StorableEntity {
|
|
|
121
121
|
### Entity Operations
|
|
122
122
|
|
|
123
123
|
```typescript
|
|
124
|
-
import { APEX,
|
|
124
|
+
import { APEX, createEntity, getEntity, updateEntity, deleteEntity, archiveEntity, destroyEntity } from "@jaypie/dynamodb";
|
|
125
125
|
|
|
126
126
|
// Create entity — indexEntity auto-populates GSI keys, createdAt, updatedAt
|
|
127
|
-
const record = await
|
|
127
|
+
const record = await createEntity({
|
|
128
128
|
entity: {
|
|
129
129
|
model: "record",
|
|
130
130
|
id: crypto.randomUUID(),
|
|
@@ -157,7 +157,7 @@ await destroyEntity({ id: "abc-123" });
|
|
|
157
157
|
|
|
158
158
|
| Function | Description |
|
|
159
159
|
|----------|-------------|
|
|
160
|
-
| `
|
|
160
|
+
| `createEntity({ entity })` | Create entity; returns `null` if `id` exists (conditional `attribute_not_exists(id)`) |
|
|
161
161
|
| `getEntity({ id })` | Get by primary key (id only) |
|
|
162
162
|
| `updateEntity({ entity })` | Update (sets `updatedAt`, re-indexes) |
|
|
163
163
|
| `deleteEntity({ id })` | Soft delete (`deletedAt`, `#deleted` suffix on GSI pk) |
|
|
@@ -169,16 +169,16 @@ await destroyEntity({ id: "abc-123" });
|
|
|
169
169
|
The `scope` field enables parent-child relationships:
|
|
170
170
|
|
|
171
171
|
```typescript
|
|
172
|
-
import { APEX, calculateScope,
|
|
172
|
+
import { APEX, calculateScope, createEntity, queryByScope } from "@jaypie/dynamodb";
|
|
173
173
|
|
|
174
174
|
// Root-level entity: scope = APEX ("@")
|
|
175
|
-
await
|
|
175
|
+
await createEntity({ entity: { model: "chat", scope: APEX, ... } });
|
|
176
176
|
|
|
177
177
|
// Child entity: scope = "{parent.model}#{parent.id}"
|
|
178
178
|
const chat = { model: "chat", id: "abc-123" };
|
|
179
179
|
const messageScope = calculateScope(chat); // "chat#abc-123"
|
|
180
180
|
|
|
181
|
-
await
|
|
181
|
+
await createEntity({
|
|
182
182
|
entity: { model: "message", scope: messageScope, ... },
|
|
183
183
|
});
|
|
184
184
|
|
|
@@ -394,7 +394,7 @@ Mock `@jaypie/dynamodb` via testkit. Key builders and `indexEntity` work correct
|
|
|
394
394
|
import {
|
|
395
395
|
APEX,
|
|
396
396
|
indexEntity,
|
|
397
|
-
|
|
397
|
+
createEntity,
|
|
398
398
|
queryByScope,
|
|
399
399
|
seedEntities,
|
|
400
400
|
} from "@jaypie/testkit/mock";
|