n8n-nodes-dingtalk-card 0.3.0 → 0.4.0-beta.2
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/CHANGELOG.md +11 -3
- package/README.md +9 -24
- package/dist/nodes/DingTalkCard/DingTalkCard.node.js +18 -3
- package/dist/nodes/DingTalkCard/presentation.js +114 -0
- package/docs/API.md +4 -0
- package/docs/PRESENTATION.md +87 -0
- package/docs/ROADMAP.md +12 -8
- package/docs/VERIFICATION.md +74 -6
- package/examples/presentation/action.json +4 -0
- package/examples/presentation/alert.json +4 -0
- package/examples/presentation/digest.json +4 -0
- package/examples/presentation/report.json +4 -0
- package/examples/presentation/status.json +4 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.4.0-beta.2 (prerelease)
|
|
4
|
+
|
|
5
|
+
Adds the fixed AI-host compatibility value `flowStatus: "3"` to Presentation `cardParamMap`, preserving all 13 Presentation contract fields. Real Mac DingTalk visual acceptance passed with the user-published AI-card template when `flowStatus=3` was supplied: all 13 Presentation fields and the summary rendered. No private template, group, or card identifiers are recorded. The package ships no DingTalk templates. npm `latest` remains stable at `0.3.0`.
|
|
6
|
+
|
|
7
|
+
## 0.4.0-beta.1 (published beta)
|
|
8
|
+
|
|
9
|
+
Adds opt-in Presentation Card Data Mode for Create & Deliver and Update. Version 1 descriptors cover alert, status, digest, action presentation metadata, and report families, with deterministic validation and mapping to string-valued `cardParamMap` entries. Includes template variable contract documentation and examples. Status transitions are guidance only; Action does not route or execute. On self-hosted production n8n/runners 2.44.6, supported UI install, loaded schema, valid status Presentation Update, and full Presentation-mode Create & Deliver/Streaming Update/Finalize/final whole-body JSON Update transport lifecycle passed, including legacy lifecycle compatibility. The legacy public AI template used does not satisfy the v0.4 template variable contract; visual Presentation rendering/template acceptance remains pending a user-published matching template. No DingTalk templates are shipped. The public beta is published as `beta -> 0.4.0-beta.1`; npm `latest` remains `0.3.0`. The release and production acceptance evidence are recorded in [verification](docs/VERIFICATION.md#v040-beta1-production-install-and-connected-instance-transport-acceptance-2026-10-25). v0.5 callback/action normalization and v0.6 renderer/A2UI work remain deferred.
|
|
10
|
+
|
|
11
|
+
## 0.3.0 (stable)
|
|
4
12
|
|
|
5
13
|
Promotes the published v0.3.0-beta.1 package to stable without adding node behavior. Includes guided Form String/JSON card parameter values, sanitized normalized outbound `errorDetails`, stable caller-controlled `outTrackId` recovery guidance, and the existing Stream callback behavior. Reusing an ID does not guarantee Create deduplication or upsert.
|
|
6
14
|
|
|
7
|
-
Stable live acceptance on connected n8n 2.44.5 passed for Robot Direct Message and whole-body JSON Create & Deliver through Update, Streaming Update, Finalize and final JSON Update. Repeated Create using one caller-controlled `outTrackId` was accepted in the tested path; no deduplication or delivery guarantee is implied. A v0.3 interaction-card button click reached DingTalk Card Trigger through a Stream callback and its downstream asynchronous Update succeeded. The temporary test listener was unpublished after the test. Earlier user-performed Community Nodes UI uninstall/reinstall restored package, manifest and installed-version consistency
|
|
15
|
+
Stable live acceptance on connected n8n 2.44.5 passed for Robot Direct Message and whole-body JSON Create & Deliver through Update, Streaming Update, Finalize and final JSON Update. Repeated Create using one caller-controlled `outTrackId` was accepted in the tested path; no deduplication or delivery guarantee is implied. A v0.3 interaction-card button click reached DingTalk Card Trigger through a Stream callback and its downstream asynchronous Update succeeded. The temporary test listener was unpublished after the test. Earlier user-performed Community Nodes UI uninstall/reinstall restored package, manifest and installed-version consistency. npm update-discovery reports stable `0.3.0` as latest for an installed `0.3.0-beta.1`; this does not claim that the n8n UI Update button was clicked or observed. Stable upgrade remains a user-operated supported Community Nodes UI action.
|
|
8
16
|
|
|
9
|
-
This release closes the v0.3.0 stable acceptance scope. It does not certify v1.0, other templates or form interactions, reconnect/failure behavior, or stable n8n versions beyond the tested instance. See [verification](docs/VERIFICATION.md#v030-stable-release-
|
|
17
|
+
This release closes the v0.3.0 stable acceptance scope. It does not certify v1.0, other templates or form interactions, reconnect/failure behavior, or stable n8n versions beyond the tested instance. See [verification](docs/VERIFICATION.md#v030-stable-release-2026-10-24) for publication, provenance and canonical asset evidence.
|
|
10
18
|
|
|
11
19
|
## 0.2.0-beta.1 (prerelease)
|
|
12
20
|
|
package/README.md
CHANGED
|
@@ -2,34 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
Focused n8n community nodes for the **DingTalk Card Platform lifecycle and Stream card callbacks**.
|
|
4
4
|
|
|
5
|
-
**v0.3.0 is
|
|
5
|
+
**v0.3.0 is the stable release.** It adds guided Form String/JSON card parameter values, additive sanitized normalized outbound error details, and stable-ID recovery guidance with a packaged fixture; existing v0.2 Stream behavior is preserved. Connected-instance acceptance on self-hosted production n8n 2.44.5 closes the documented v0.3 stable scope; this does not certify v1.0 or untested platform/runtime behavior. This project is not n8n-verified and is not affiliated with DingTalk or n8n.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**v0.4.0-beta.2 is a prerelease** for the v0.4.0 milestone. It adds the fixed AI-host compatibility value `flowStatus="3"` to Presentation card data. Real Mac DingTalk visual acceptance passed with the user-published AI-card template when this value was supplied; all 13 Presentation fields and the summary rendered. The package ships no DingTalk templates. See the [presentation contract](docs/PRESENTATION.md) and [release verification](docs/VERIFICATION.md).
|
|
8
|
+
|
|
9
|
+
The npm `beta` dist-tag will resolve to `0.4.0-beta.2` after publication; npm `latest` remains stable at `0.3.0`. Releases use GitHub Actions Trusted Publisher/OIDC with provenance. Beta publication leaves `latest` unchanged now that a stable version exists.
|
|
8
10
|
|
|
9
11
|
It provides **DingTalk Card**, **DingTalk Card Trigger**, and the shared **DingTalk Card API** enterprise app credential. It does not implement OA, todo, tables or general robot messaging, and does not depend on `@cryozerolabs/n8n-nodes-dingtalk`. Robot delivery fields here exist only to deliver Card Platform instances.
|
|
10
12
|
|
|
11
13
|
## Installation
|
|
12
14
|
|
|
13
|
-
Requires Node.js 24+ and a compatible n8n installation. Development compiles and loads the node against `n8n-workflow` 2.44.2 (the dependency of
|
|
14
|
-
|
|
15
|
-
Install the package in self-hosted n8n from **Settings > Community Nodes > Install** by entering `n8n-nodes-dingtalk-card@0.3.0` after stable publication (or `@latest`). Community-node installation requires an Owner or Admin account and may be disabled by instance policy. npm installation does not certify live DingTalk behavior. The tested live scope and remaining limits are documented below; stable Update-button verification is scheduled after publication; v1.0 readiness is not certified.
|
|
16
|
-
|
|
17
|
-
To rebuild the previously published v0.2.0-beta.1 artifact from its tag:
|
|
18
|
-
|
|
19
|
-
```sh
|
|
20
|
-
git clone https://github.com/NTLx/n8n-nodes-dingtalk-card.git
|
|
21
|
-
cd n8n-nodes-dingtalk-card
|
|
22
|
-
git checkout v0.2.0-beta.1
|
|
23
|
-
npm ci
|
|
24
|
-
npm run build
|
|
25
|
-
npm test
|
|
26
|
-
npm pack
|
|
27
|
-
# Install the resulting tgz in your self-hosted n8n community-node directory:
|
|
28
|
-
cd ~/.n8n/nodes
|
|
29
|
-
npm install /absolute/path/to/n8n-nodes-dingtalk-card-0.2.0-beta.1.tgz
|
|
30
|
-
```
|
|
15
|
+
Requires Node.js 24+ and a compatible n8n installation. Development compiles and loads the node against `n8n-workflow` 2.44.2 (the dependency of n8n 2.44.6). Production install and the documented connected-instance transport paths passed on self-hosted n8n/runners 2.44.6; client pixel-perfect visual inspection was not independently performed, and other runtime versions are not certified. CI uses Node 24. n8n 2.44.6 declares Node >=24; this takes precedence over older starter guidance mentioning Node 22.
|
|
31
16
|
|
|
32
|
-
|
|
17
|
+
Install or upgrade the package through n8n's supported **Settings > Community Nodes** lifecycle. To install, enter `n8n-nodes-dingtalk-card` (stable) or `n8n-nodes-dingtalk-card@beta` (current beta). To install or upgrade to an exact prerelease version in the UI, uninstall the package and reinstall it with the exact version, for example `n8n-nodes-dingtalk-card@0.4.0-beta.1`; n8n's standard Update action targets the latest version. Where available, the official Public API `POST /api/v1/community-packages` and `PATCH /api/v1/community-packages/{packageName}` support package management and explicit update versions; use API keys scoped to `communityPackage:list` and `communityPackage:update` as applicable. See [n8n Community Nodes installation and management](https://docs.n8n.io/integrations/community-nodes/installation-and-management/gui-installation/) and [Public API authentication and scopes](https://docs.n8n.io/api/authentication/). Community-node installation requires an Owner or Admin account and may be disabled by instance policy. Installation does not certify live DingTalk behavior. The tested live scope and remaining limits are documented below; v1.0 readiness is not certified.
|
|
33
18
|
|
|
34
19
|
## Credentials
|
|
35
20
|
|
|
@@ -50,7 +35,7 @@ The credential test acquires an app token only. It does not send a card or prove
|
|
|
50
35
|
| Streaming Update | PUT one frame with `key`, `content`, `guid`, `isFull`, `isFinalize`, `isError` |
|
|
51
36
|
| Finalize | PUT a terminal streaming frame: success sets `isFinalize=true,isError=false`; failure sets `isError=true,isFinalize=false` |
|
|
52
37
|
|
|
53
|
-
**Form** input provides guided fields. Card Data has its own Form/JSON selector; the JSON form is the full `{"cardParamMap":{"title":"Example"}}` object. Form parameters default to **String** mode, which preserves existing values; choose **JSON** mode to enter an object, array, or scalar that is serialized into the string required by `cardParamMap`. **JSON** input accepts the official request body for advanced delivery/space models, `privateData`, `cardUpdateOptions`, `userIdType`, or `callbackType: "STREAM"`. Fields pass through; you are responsible for model/space consistency.
|
|
38
|
+
**Form** input provides guided fields. Card Data has its own Form/JSON/Presentation selector; the JSON form is the full `{"cardParamMap":{"title":"Example"}}` object. Presentation maps the v1 alert/status/digest/action/report descriptor into string-valued template variables. Form parameters default to **String** mode, which preserves existing values; choose **JSON** mode to enter an object, array, or scalar that is serialized into the string required by `cardParamMap`. **JSON** input accepts the official request body for advanced delivery/space models, `privateData`, `cardUpdateOptions`, `userIdType`, or `callbackType: "STREAM"`. Fields pass through; you are responsible for model/space consistency. Presentation variable names are a contract for templates you publish; no platform template or component is included or verified by this package.
|
|
54
39
|
|
|
55
40
|
`outTrackId` identifies a card within DingTalk's app context and is always returned. Create generates a UUID when missing/empty; that generated ID is stable only within that execution. A rerun may generate a different ID. To refer to the same logical card across executions, derive and supply the ID from a stable business/event key, such as an order ID plus an immutable event ID; do not derive it from a random value generated on each attempt. Preserve that same caller-controlled ID for any manual replay. A repeated Create with the same ID does not guarantee deduplication or upsert and is not an Update: verify whether the card/delivery already exists, then use Update if the card exists. Store the create output before later lifecycle operations.
|
|
56
41
|
|
|
@@ -124,7 +109,7 @@ Uses the official [n8n node CLI](https://docs.n8n.io/connect/create-nodes/build-
|
|
|
124
109
|
|
|
125
110
|
Programmatic execution is intentional: shared token handling, strict 2xx/partial-delivery failure checks, generated identifier propagation and sanitized item-level errors are implemented once, separated from pure payload builders. The current custom credential-test context in `n8n-workflow` exposes only the legacy `request` helper; that single call has a documented lint exception and sanitized error boundary. Main execution uses `httpRequest`. Pure helper errors are converted to `NodeOperationError` at the execution boundary.
|
|
126
111
|
|
|
127
|
-
See [verification record](docs/VERIFICATION.md) for exact local/CI gates, dependency findings and limitations.
|
|
112
|
+
See [verification record](docs/VERIFICATION.md) for release identity, public artifact digests, provenance, update-discovery evidence, exact local/CI gates, dependency findings and limitations.
|
|
128
113
|
|
|
129
114
|
## Roadmap
|
|
130
115
|
|
|
@@ -132,6 +117,6 @@ The direction is **Interactive-first, AI-when-needed**: use DingTalk cards for p
|
|
|
132
117
|
|
|
133
118
|
The durable architecture, scope boundaries, controlled A2UI contract, and anti-drift decision rules are in the [design baseline](docs/DESIGN.md); the roadmap is subordinate to it.
|
|
134
119
|
|
|
135
|
-
Historical milestones: **v0.1.0-beta.1** introduced outbound Card Platform lifecycle operations; **v0.2.0-beta.1** added the narrow Stream callback trigger and explicit callback opt-in, with one real request-button path verified; **v0.3.0-beta.1** added Form String/JSON values, normalized outbound error details and stable-ID recovery guidance
|
|
120
|
+
Historical milestones: **v0.1.0-beta.1** introduced outbound Card Platform lifecycle operations; **v0.2.0-beta.1** added the narrow Stream callback trigger and explicit callback opt-in, with one real request-button path verified; **v0.3.0-beta.1** added Form String/JSON values, normalized outbound error details and stable-ID recovery guidance, and **v0.3.0** is its stable release. Stable acceptance evidence and limits are recorded in [verification](docs/VERIFICATION.md#v030-stable-release-2026-10-24).
|
|
136
121
|
|
|
137
122
|
MIT licensed. Please remove identifiers, card data and credentials before filing an issue.
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DingTalkCard = void 0;
|
|
4
4
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
5
|
const payload_1 = require("./payload");
|
|
6
|
+
const presentation_1 = require("./presentation");
|
|
6
7
|
const transport_1 = require("./transport");
|
|
7
8
|
const operations = ['createAndDeliver', 'update'];
|
|
8
9
|
const streamOperations = ['stream', 'finalize'];
|
|
@@ -52,6 +53,17 @@ const properties = [
|
|
|
52
53
|
],
|
|
53
54
|
description: 'Use guided fields or supply the official API request body',
|
|
54
55
|
},
|
|
56
|
+
{
|
|
57
|
+
displayName: 'Presentation Descriptor',
|
|
58
|
+
name: 'presentationDescriptor',
|
|
59
|
+
type: 'json',
|
|
60
|
+
default: '{}',
|
|
61
|
+
required: true,
|
|
62
|
+
displayOptions: {
|
|
63
|
+
show: { inputMode: ['form'], operation: operations, cardDataMode: ['presentation'] },
|
|
64
|
+
},
|
|
65
|
+
description: 'Versioned presentation descriptor mapped to the documented template variables',
|
|
66
|
+
},
|
|
55
67
|
{
|
|
56
68
|
displayName: 'Request Body',
|
|
57
69
|
name: 'requestBody',
|
|
@@ -95,6 +107,7 @@ const properties = [
|
|
|
95
107
|
options: [
|
|
96
108
|
{ name: 'Form', value: 'form' },
|
|
97
109
|
{ name: 'JSON', value: 'json' },
|
|
110
|
+
{ name: 'Presentation', value: 'presentation' },
|
|
98
111
|
],
|
|
99
112
|
displayOptions: { show: { inputMode: ['form'], operation: operations } },
|
|
100
113
|
},
|
|
@@ -304,9 +317,11 @@ class DingTalkCard {
|
|
|
304
317
|
else {
|
|
305
318
|
body.outTrackId = this.getNodeParameter('outTrackId', i);
|
|
306
319
|
if (operations.includes(operation)) {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
320
|
+
const cardDataMode = this.getNodeParameter('cardDataMode', i);
|
|
321
|
+
body.cardData = cardDataMode === 'json'
|
|
322
|
+
? (0, payload_1.jsonObject)(this.getNodeParameter('cardData', i), 'Card Data')
|
|
323
|
+
: cardDataMode === 'presentation'
|
|
324
|
+
? (0, presentation_1.presentationCardData)((0, payload_1.jsonObject)(this.getNodeParameter('presentationDescriptor', i), 'Presentation Descriptor'))
|
|
310
325
|
: (0, payload_1.formCardData)(this.getNodeParameter('cardParameters.parameters', i, []));
|
|
311
326
|
if (operation === 'createAndDeliver') {
|
|
312
327
|
body.cardTemplateId = this.getNodeParameter('cardTemplateId', i);
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.presentationCardData = presentationCardData;
|
|
4
|
+
const transport_1 = require("./transport");
|
|
5
|
+
const tones = ['neutral', 'info', 'success', 'warning', 'danger'];
|
|
6
|
+
const states = ['idle', 'running', 'success', 'failed', 'cancelled'];
|
|
7
|
+
function record(value, label) {
|
|
8
|
+
if (!(0, transport_1.object)(value))
|
|
9
|
+
throw new transport_1.CardError(`Presentation ${label} must be an object.`);
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
function fields(value, allowed, label) {
|
|
13
|
+
for (const key of Object.keys(value))
|
|
14
|
+
if (!allowed.includes(key))
|
|
15
|
+
throw new transport_1.CardError(`Unknown Presentation ${label} field "${key}".`);
|
|
16
|
+
}
|
|
17
|
+
function string(value, label, max = 1000) {
|
|
18
|
+
if (typeof value !== 'string' || !value.trim() || value.length > max)
|
|
19
|
+
throw new transport_1.CardError(`Presentation ${label} must be a non-empty string of at most ${max} characters.`);
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
function optionalString(value, label, max = 1000) {
|
|
23
|
+
return value === undefined ? undefined : string(value, label, max);
|
|
24
|
+
}
|
|
25
|
+
function tone(value) {
|
|
26
|
+
if (typeof value !== 'string' || !tones.includes(value))
|
|
27
|
+
throw new transport_1.CardError(`Presentation tone must be one of: ${tones.join(', ')}.`);
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
function list(value, label) {
|
|
31
|
+
if (!Array.isArray(value) || value.length < 1 || value.length > 20)
|
|
32
|
+
throw new transport_1.CardError(`Presentation ${label} must contain between 1 and 20 items.`);
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
function json(value) {
|
|
36
|
+
return JSON.stringify(value);
|
|
37
|
+
}
|
|
38
|
+
function presentationCardData(input) {
|
|
39
|
+
const d = record(input, 'descriptor');
|
|
40
|
+
if (d.version !== '1')
|
|
41
|
+
throw new transport_1.CardError('Unsupported Presentation version. Supported version: "1".');
|
|
42
|
+
const family = d.family;
|
|
43
|
+
if (!['alert', 'status', 'digest', 'action', 'report'].includes(String(family)))
|
|
44
|
+
throw new transport_1.CardError('Unsupported Presentation family.');
|
|
45
|
+
const common = ['version', 'family', 'title', 'summary', 'tone'];
|
|
46
|
+
const map = Object.create(null);
|
|
47
|
+
map.presentationVersion = '1';
|
|
48
|
+
map.presentationFamily = family;
|
|
49
|
+
map.flowStatus = '3';
|
|
50
|
+
map.title = string(d.title, 'title', 200);
|
|
51
|
+
const summary = optionalString(d.summary, 'summary');
|
|
52
|
+
if (summary !== undefined)
|
|
53
|
+
map.summary = summary;
|
|
54
|
+
map.tone = tone(d.tone);
|
|
55
|
+
const familyFields = {
|
|
56
|
+
alert: ['source', 'occurredAt'],
|
|
57
|
+
status: ['state', 'details'],
|
|
58
|
+
digest: ['items'],
|
|
59
|
+
action: ['label', 'description'],
|
|
60
|
+
report: ['sections'],
|
|
61
|
+
};
|
|
62
|
+
fields(d, [...common, ...familyFields[family]], 'descriptor');
|
|
63
|
+
switch (family) {
|
|
64
|
+
case 'alert': {
|
|
65
|
+
const source = optionalString(d.source, 'source', 200);
|
|
66
|
+
const occurredAt = optionalString(d.occurredAt, 'occurredAt', 100);
|
|
67
|
+
if (source !== undefined)
|
|
68
|
+
map.source = source;
|
|
69
|
+
if (occurredAt !== undefined)
|
|
70
|
+
map.occurredAt = occurredAt;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
case 'status':
|
|
74
|
+
if (typeof d.state !== 'string' || !states.includes(d.state))
|
|
75
|
+
throw new transport_1.CardError(`Presentation state must be one of: ${states.join(', ')}.`);
|
|
76
|
+
map.state = d.state;
|
|
77
|
+
if (d.details !== undefined)
|
|
78
|
+
map.details = string(d.details, 'details');
|
|
79
|
+
break;
|
|
80
|
+
case 'digest': {
|
|
81
|
+
const items = list(d.items, 'items').map((raw, i) => {
|
|
82
|
+
const item = record(raw, `items[${i}]`);
|
|
83
|
+
fields(item, ['title', 'summary', 'tone'], `items[${i}]`);
|
|
84
|
+
const entry = { title: string(item.title, `items[${i}].title`, 200) };
|
|
85
|
+
const itemSummary = optionalString(item.summary, `items[${i}].summary`);
|
|
86
|
+
if (itemSummary !== undefined)
|
|
87
|
+
entry.summary = itemSummary;
|
|
88
|
+
if (item.tone !== undefined)
|
|
89
|
+
entry.tone = tone(item.tone);
|
|
90
|
+
return entry;
|
|
91
|
+
});
|
|
92
|
+
map.items = json(items);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case 'action':
|
|
96
|
+
map.label = string(d.label, 'label', 100);
|
|
97
|
+
if (d.description !== undefined)
|
|
98
|
+
map.description = string(d.description, 'description');
|
|
99
|
+
break;
|
|
100
|
+
case 'report': {
|
|
101
|
+
const sections = list(d.sections, 'sections').map((raw, i) => {
|
|
102
|
+
const section = record(raw, `sections[${i}]`);
|
|
103
|
+
fields(section, ['heading', 'body'], `sections[${i}]`);
|
|
104
|
+
return {
|
|
105
|
+
heading: string(section.heading, `sections[${i}].heading`, 200),
|
|
106
|
+
body: string(section.body, `sections[${i}].body`),
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
map.sections = json(sections);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return { cardParamMap: map };
|
|
114
|
+
}
|
package/docs/API.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# API contracts checked 2026-10-24
|
|
2
2
|
|
|
3
|
+
## Presentation Card Data Mode (v0.4.0 development)
|
|
4
|
+
|
|
5
|
+
For Form input on Create & Deliver or Update, Card Data Mode `Presentation` accepts the v1 descriptor documented in [PRESENTATION.md](PRESENTATION.md) and produces existing `cardData.cardParamMap` string values. It is opt-in; Card Data Form/JSON and whole-body Input Mode JSON contracts are unchanged. This mode is a stateless adapter and does not ship templates, render components, route actions, or enforce status transitions.
|
|
6
|
+
|
|
3
7
|
Primary documentation was fetched from current DingTalk documentation pages and their published backing content at `https://icms-document.oss-cn-beijing.aliyuncs.com/zh-CN/dingtalk/{namespace}/topics/{slug}.html`. The backing URL is how the current documentation frontend renders the body; it is not an application endpoint. That documentation check did not make authenticated calls; the later connected-instance live E2E is recorded below.
|
|
4
8
|
|
|
5
9
|
| Purpose | Method and path on `https://api.dingtalk.com` | Verified contract |
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Presentation descriptor v1
|
|
2
|
+
|
|
3
|
+
The Presentation Card Data Mode is a stateless adapter from a small, versioned descriptor to the existing Form-mode `cardData.cardParamMap` boundary. It does not render a card or verify DingTalk template components. The package does **not** ship DingTalk platform templates. Users must create, publish, and associate templates whose variables match the mappings below.
|
|
4
|
+
|
|
5
|
+
## Contract
|
|
6
|
+
|
|
7
|
+
Every descriptor is a JSON object with required `version: "1"`, `family`, `title`, and `tone`. `family` is one of `alert`, `status`, `digest`, `action`, or `report`. `title` is a non-empty string up to 200 characters. Optional `summary` is a non-empty string up to 1000 characters. Unknown fields are rejected at the descriptor and nested-object levels. Strings are not interpreted as HTML, code, or template fragments. No arbitrary colors, style values, or component trees are accepted.
|
|
8
|
+
|
|
9
|
+
Semantic `tone` values are `neutral`, `info`, `success`, `warning`, and `danger`. They are labels for user-authored template logic, not colors imposed by this package. Templates may choose their own visual treatment for these tokens.
|
|
10
|
+
|
|
11
|
+
All list families require 1–20 entries. Digest items have required `title` (up to 200 characters), optional `summary` (up to 1000), and optional `tone`. Report sections have required `heading` (up to 200) and `body` (up to 1000). Unknown fields or malformed entries fail validation. No external schema library is used.
|
|
12
|
+
|
|
13
|
+
## Families and exact variable mapping
|
|
14
|
+
|
|
15
|
+
Every family maps the 13 contract variables described below. Presentation mode also adds the AI-host compatibility field `flowStatus: "3"` to the public `cardParamMap`; it is not a descriptor field or part of the Presentation contract. This fixed value cannot be overridden by descriptor input. The current DingTalk AI Card builder templates (`type=im`, `schemaVersion=3.0.0`, `extendType=AI`) require completed-state `flowStatus` for `AICardContainer` to select its completed content branch. The 13 contract variables retain their existing meanings and encodings.
|
|
16
|
+
|
|
17
|
+
Every family maps these contract entries:
|
|
18
|
+
|
|
19
|
+
| Descriptor value | `cardParamMap` variable | Encoding |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| Contract identity | `presentationVersion` = `"1"` | string |
|
|
22
|
+
| `family` | `presentationFamily` | string |
|
|
23
|
+
| `title` | `title` | string |
|
|
24
|
+
| optional `summary` | `summary` | string, omitted when absent |
|
|
25
|
+
| `tone` | `tone` | symbolic string |
|
|
26
|
+
|
|
27
|
+
Family-specific fields:
|
|
28
|
+
|
|
29
|
+
| Family | Descriptor fields | `cardParamMap` entries |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| `alert` | optional `source` (200 chars), `occurredAt` (100 chars) | `source`, `occurredAt`, omitted when absent |
|
|
32
|
+
| `status` | required `state`; optional `details` | `state`, optional `details` |
|
|
33
|
+
| `digest` | required `items` array | `items` as compact JSON string |
|
|
34
|
+
| `action` | required `label` (100 chars); optional `description` | `label`, optional `description` |
|
|
35
|
+
| `report` | required `sections` array | `sections` as compact JSON string |
|
|
36
|
+
|
|
37
|
+
The only status states are `idle`, `running`, `success`, `failed`, and `cancelled`. Digest and report objects serialize with stable field order as shown in the schema (`title`, `summary`, `tone`; and `heading`, `body`). All resulting values are strings, as required by the existing Card Data boundary. The mapper does not reorder list entries. Thus the payload contains 13 contract variables plus one AI-host compatibility field.
|
|
38
|
+
|
|
39
|
+
### Template acceptance rule
|
|
40
|
+
|
|
41
|
+
A successful DingTalk Create & Deliver response proves transport acceptance only. It does not prove that the selected template defines or binds the supplied variables, or that the card renders them. Accept the template contract after inspecting rendered-card evidence or template-definition/export evidence showing the required variables are defined and bound, together with live transport through the selected published template. This establishes template-contract acceptance; it does not by itself claim client pixel-perfect visual inspection.
|
|
42
|
+
|
|
43
|
+
`Action` is presentation metadata only. `label` and `description` are display strings. They do not define a callback ID, route, authorization, executable action, or platform button. Workflow routing and callback contracts are outside this version.
|
|
44
|
+
|
|
45
|
+
## Status and transitions
|
|
46
|
+
|
|
47
|
+
The adapter is stateless: it validates one descriptor and maps it to one `cardData` value. It does not remember prior status or enforce transitions. As workflow guidance, a task may progress from `idle` to `running`, then to `success`, `failed`, or `cancelled`. A workflow may also update a terminal card later when its business process explicitly supports retry or correction. Choose and persist transition policy in the workflow layer; the enum only bounds presentation vocabulary.
|
|
48
|
+
|
|
49
|
+
## Examples
|
|
50
|
+
|
|
51
|
+
Runnable descriptor JSON files and their mapped card data are in [`examples/presentation`](../examples/presentation/).
|
|
52
|
+
|
|
53
|
+
### Alert
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{"version":"1","family":"alert","title":"Database unavailable","summary":"Primary database health check failed.","tone":"danger","source":"health-check","occurredAt":"2026-10-25T08:30:00Z"}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Status
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{"version":"1","family":"status","title":"Nightly backup","summary":"Archive upload is running.","tone":"info","state":"running","details":"12 of 40 GB uploaded"}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Digest
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{"version":"1","family":"digest","title":"Engineering digest","tone":"neutral","items":[{"title":"Build passed","summary":"Main branch","tone":"success"}]}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Action
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{"version":"1","family":"action","title":"Review deployment","tone":"warning","label":"Open deployment details","description":"Display metadata only; workflow behavior is configured separately."}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Report
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{"version":"1","family":"report","title":"Daily operations","summary":"Three services checked.","tone":"success","sections":[{"heading":"Availability","body":"All monitored services responded."}]}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Compatibility and boundaries
|
|
84
|
+
|
|
85
|
+
Presentation mode is opt-in under Form input for Create & Deliver and Update. Its output is passed through the existing request builder. Existing Form parameters, Card Data JSON, whole-body Input Mode JSON, request construction, and output fields retain their behavior. The template ID is always user supplied for Create & Deliver; this package does not include or publish templates.
|
|
86
|
+
|
|
87
|
+
This is an adapter, not a renderer or template registry. It does not claim support for specific DingTalk components or visual behavior. v0.5 normalized callback/action contracts and v0.6 controlled A2UI/component rendering are explicitly deferred. There is no executable action routing, arbitrary HTML/code, arbitrary styling, persistent state, or general component allowlist runtime in v1.
|
package/docs/ROADMAP.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
This roadmap is subordinate to the project's [design baseline](DESIGN.md), which governs architecture, scope, non-goals, and acceptance boundaries. Roadmap items may sequence work within those boundaries but cannot override them; resolve conflicts by updating the proposal to fit the baseline or deliberately revising the baseline first.
|
|
4
4
|
|
|
5
|
-
This roadmap starts from the published **v0.3.0
|
|
5
|
+
This roadmap starts from the published **v0.3.0** stable state, with **v0.3.0-beta.1** retained as its prerelease. It describes intended milestones, not released capabilities. The current release and its tested limits remain documented in the [README](../README.md), [API contracts](API.md), and [verification record](VERIFICATION.md). Dates are omitted; milestones are semantic versions, not calendar commitments.
|
|
6
|
+
|
|
7
|
+
The repository package version is **0.4.0-beta.1**, publicly published as a beta. npm `beta` resolves to `0.4.0-beta.1`; `latest` remains stable at `0.3.0`. The v0.4.0 Presentation Contract & Template Kit is implemented and accepted, including live use of a user-published contract template. The package ships no DingTalk templates. See [final template-contract acceptance](VERIFICATION.md#v040-beta1-final-presentation-template-contract-acceptance-2026-10-25).
|
|
6
8
|
|
|
7
9
|
## Vision and product principle
|
|
8
10
|
|
|
@@ -27,7 +29,7 @@ Descriptors produced with model assistance may be considered only after determin
|
|
|
27
29
|
|
|
28
30
|
## Milestones
|
|
29
31
|
|
|
30
|
-
### v0.3.0 — stable release (
|
|
32
|
+
### v0.3.0 — stable release (released)
|
|
31
33
|
|
|
32
34
|
**Objective:** Close acceptance for the existing beta surface, remove the prerelease qualifier, and establish a reliable stable baseline. No major new product surface.
|
|
33
35
|
|
|
@@ -39,28 +41,30 @@ Descriptors produced with model assistance may be considered only after determin
|
|
|
39
41
|
- Characterize repeated Create behavior with the same `outTrackId`; do not promise deduplication or upsert.
|
|
40
42
|
- Regression coverage for existing v0.1/v0.2/v0.3 behavior and n8n UI install/update lifecycle acceptance.
|
|
41
43
|
|
|
42
|
-
**Acceptance gates (closed
|
|
44
|
+
**Acceptance gates (closed):** Scoped live and local evidence, release provenance, canonical artifact digest and npm update-discovery evidence are recorded in [verification](VERIFICATION.md#v030-stable-release-2026-10-24). Robot Direct Message and whole-body JSON lifecycles passed; a real v0.3 button callback reached the trigger and asynchronous Update succeeded; repeated Create with one caller-controlled `outTrackId` was accepted in the tested path without implying deduplication/upsert. A user-performed Community Nodes UI uninstall/reinstall restored package/manifest/installed-version consistency. Stable upgrade remains a user-operated supported Community Nodes UI action; the isolated update-discovery check does not claim the UI button was clicked or observed.
|
|
43
45
|
|
|
44
46
|
**Non-goals / deferrals:** No new card families, generalized interaction schema, A2UI renderer, business workflow suite, or broad DingTalk API coverage.
|
|
45
47
|
|
|
46
48
|
**Compatibility and migration:** Preserve existing Form/JSON behavior, callback opt-in, output fields, and saved workflow behavior. Same-ID Create semantics remain explicitly non-guaranteed.
|
|
47
49
|
|
|
48
|
-
### v0.4.0 — Presentation Contract & Template Kit
|
|
50
|
+
### v0.4.0 — Presentation Contract & Template Kit (published beta; acceptance complete, ready for stable promotion)
|
|
49
51
|
|
|
50
52
|
**Objective:** Define how workflows describe useful card presentations independently of a particular template.
|
|
51
53
|
|
|
52
|
-
**Main deliverables:**
|
|
54
|
+
**Main deliverables (implemented):**
|
|
53
55
|
|
|
54
|
-
-
|
|
56
|
+
- Versioned presentation schema, example payloads, and a template variable contract.
|
|
55
57
|
- Alert, Status, Digest, Action, and Report card families.
|
|
56
58
|
- Design tokens and visual hierarchy guidance, with card state transitions.
|
|
57
59
|
- Low-level raw JSON mode retained for expert API use.
|
|
58
60
|
|
|
59
|
-
|
|
61
|
+
The implementation is a deterministic stateless adapter to the existing Form-mode `cardData.cardParamMap` boundary. It does not ship DingTalk templates or claim verified component support. Status transition descriptions are workflow guidance only.
|
|
62
|
+
|
|
63
|
+
**Acceptance gates (complete):** Local schema validation, family examples, mapping, compatibility, and workflow-only state guidance are documented and locally verified. Production UI installation, loaded schema, adapter/API transport, and compatibility with the existing lifecycle passed on n8n/runners 2.44.6. The dedicated template definition/export established all 13 contract variables as public strings statically bound in both `editorData` and `widgetInfo`; live published-template transport passed for all five families with required and optional fields populated. Five n8n executions succeeded, with top-level DingTalk `success=true` and `deliverResults[].success=true` in every response. This is sufficient under the documented rule to pass the template contract; client pixel-perfect visual inspection was not independently performed. The beta is ready for stable promotion; stable promotion is outside this milestone's completed work.
|
|
60
64
|
|
|
61
65
|
**Non-goals / deferrals:** No arbitrary UI or HTML, no automatic template authoring, and no A2UI runtime in this milestone.
|
|
62
66
|
|
|
63
|
-
**Compatibility and migration:** The contract is additive and versioned. Existing Form and whole-body JSON modes continue to work; no existing request body is silently reinterpreted.
|
|
67
|
+
**Compatibility and migration:** The contract is additive and versioned. Existing Form and whole-body JSON modes continue to work; no existing request body is silently reinterpreted. The beta is published and production-installed through the supported UI. Transport, lifecycle, and Presentation template-contract acceptance are complete for the documented paths.
|
|
64
68
|
|
|
65
69
|
### v0.5.0 — Interaction Contract & Normalized Trigger
|
|
66
70
|
|
package/docs/VERIFICATION.md
CHANGED
|
@@ -1,8 +1,60 @@
|
|
|
1
1
|
# Release verification record — 2026-10-24
|
|
2
2
|
|
|
3
|
-
## v0.
|
|
3
|
+
## v0.4.0-beta.2 real Mac DingTalk visual acceptance — 2026-10-25
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Real Mac DingTalk visual acceptance passed with the user's published AI-card template when `flowStatus=3` was supplied. All 13 Presentation contract fields and the summary rendered. The Presentation adapter supplies the fixed public `flowStatus: "3"` compatibility field while retaining the 13 contract variables. No private template IDs or group/card identifiers are recorded.
|
|
6
|
+
|
|
7
|
+
## v0.4.0-beta.1 publication and production preflight — 2026-10-25 (historical)
|
|
8
|
+
|
|
9
|
+
The v0.4.0-beta.1 package is publicly published as a beta. This section records release identity and the read-only production preflight state at that time. Its production-upgrade and live-acceptance statements are superseded by the subsequent acceptance section below.
|
|
10
|
+
|
|
11
|
+
- Tag `v0.4.0-beta.1` points to commit `3bb7e64c5a45aa78ba82ba1547c2e037e8f89655`. GitHub Actions publish run [40110742892](https://github.com/NTLx/n8n-nodes-dingtalk-card/actions/runs/40110742892) succeeded.
|
|
12
|
+
- Public npm dist-tags are `beta -> 0.4.0-beta.1` and `latest -> 0.3.0`. Trusted Publisher/OIDC publication and provenance succeeded.
|
|
13
|
+
- The canonical GitHub prerelease asset matches the public npm tarball: **54,776 bytes**, SHA-256 `d906cd7e69379841655cd2c562558cf75bff622e4284ca58e1b9680f232c8870`.
|
|
14
|
+
- At the time of this preflight, no live DingTalk Presentation template acceptance had occurred. The package ships no DingTalk templates.
|
|
15
|
+
|
|
16
|
+
### Connected-instance production preflight
|
|
17
|
+
|
|
18
|
+
On 2026-10-25, connected production n8n and its runners were healthy on version **2.44.6**. At this preflight point the installed `n8n-nodes-dingtalk-card` was **0.3.0** and its live node schema exposed `cardDataMode` values `form` and `json` only. The official `/api/v1/community-packages` route existed and required authentication. No confirmed existing Public API credential with both `communityPackage:list` and `communityPackage:update` scopes was available on-host, and `N8N_COMMUNITY_PACKAGES` environment management was not configured.
|
|
19
|
+
|
|
20
|
+
At that point the existing DingTalk Card E2E workflow used the earlier template-variable pattern; it was not evidence of v0.4 Presentation acceptance. Production upgrade and live template E2E were then pending. No private IDs or secrets are recorded here.
|
|
21
|
+
|
|
22
|
+
## v0.4.0-beta.1 production install and connected-instance transport acceptance — 2026-10-25
|
|
23
|
+
|
|
24
|
+
Production self-hosted n8n and runners were on **2.44.6**; healthz and readiness each returned HTTP 200. The package `n8n-nodes-dingtalk-card@0.4.0-beta.1` was installed through the supported Community Nodes UI lifecycle. The host package metadata confirmed `0.4.0-beta.1`. Live `get_node_types` exposed `cardDataMode='presentation'` and `presentationDescriptor`.
|
|
25
|
+
|
|
26
|
+
Connected-instance live acceptance passed the following transport paths:
|
|
27
|
+
|
|
28
|
+
- A valid status Presentation Update was applied to an existing test card; DingTalk Update returned success.
|
|
29
|
+
- The existing draft E2E's Create & Deliver and Update steps were switched to Presentation mode. The run then completed its existing Streaming Update, Finalize, and final whole-body JSON Update; the complete live execution succeeded.
|
|
30
|
+
|
|
31
|
+
This accepts the Presentation adapter mapping, DingTalk API transport, and compatibility with the legacy lifecycle on this connected instance. The E2E used the existing legacy public AI template solely for these purposes. That template does not satisfy the v0.4 `presentationVersion`/`presentationFamily`/`title`/`tone`/... variable contract documented in [PRESENTATION.md](PRESENTATION.md). Therefore no visual Presentation rendering or matching-template acceptance is claimed. Visual/template E2E remains pending until the user publishes a template matching that contract and runs it. The package ships no DingTalk templates.
|
|
32
|
+
|
|
33
|
+
The preceding prepublication development verification remains historical and records local gates only; it makes no claim of production use at that earlier point. No real organization, group, card, credential, workflow, execution, or `outTrackId` identifiers are recorded.
|
|
34
|
+
|
|
35
|
+
## v0.4.0-beta.1 live Presentation template-contract probe — 2026-10-25
|
|
36
|
+
|
|
37
|
+
This probe records the earlier state and is superseded by the final acceptance record below.
|
|
38
|
+
|
|
39
|
+
A user-published dedicated DingTalk test template was exercised with real Create & Deliver for all five Presentation families: `alert`, `status`, `digest`, `action`, and `report`. Each descriptor populated all common fields and every family-specific optional and required field. All five API Create & Deliver calls succeeded.
|
|
40
|
+
|
|
41
|
+
A negative-control Create & Deliver using Card Data JSON with one deliberately unknown `cardParamMap` key also succeeded. This demonstrates that DingTalk API success does **not** prove a template defines or binds the supplied variables. Transport acceptance and template-variable binding/rendering acceptance are separate checks.
|
|
42
|
+
|
|
43
|
+
Full visual/template-contract acceptance remains pending rendered-card evidence or template-definition/export evidence. No real template, group, card, workflow, execution, credential, or `outTrackId` identifiers are recorded.
|
|
44
|
+
|
|
45
|
+
## v0.4.0-beta.1 final Presentation template-contract acceptance — 2026-10-25
|
|
46
|
+
|
|
47
|
+
The Presentation mapper includes the fixed public AI-host compatibility value `flowStatus: "3"` in addition to the 13 Presentation contract variables. The current AI Card builder template configuration (`type=im`, `schemaVersion=3.0.0`, `extendType=AI`) needs completed-state `flowStatus` for `AICardContainer` to select its completed content branch. The descriptor schema and 13-variable contract remain unchanged. This host compatibility behavior is covered by local unit tests; it does not constitute visual acceptance of the user's template or client rendering.
|
|
48
|
+
|
|
49
|
+
The dedicated test template was rebuilt from the user-exported DingTalk JSON as a compact `NORMAL` template with three logical components: one Grid and two BaseText components. Its 13/13 v0.4 contract variables are defined as public strings and statically bound in both `editorData` and `widgetInfo`. The user imported and published this template.
|
|
50
|
+
|
|
51
|
+
Final live connected-instance acceptance sent all five Presentation families (`alert`, `status`, `digest`, `action`, and `report`) through the published template. Required and optional fields were populated for each family. All five n8n executions succeeded; every DingTalk response had top-level `success=true` and `deliverResults[].success=true`.
|
|
52
|
+
|
|
53
|
+
Under the documented template acceptance rule, template-definition/export evidence together with live transport through the published template is sufficient to mark the Presentation template contract **PASS**. Client pixel-perfect visual inspection was not independently performed and is not claimed. This closes v0.4.0-beta.1 acceptance; the release is ready for stable promotion. No stable release was published or relabeled as part of this acceptance. No real template, group, card, workflow, execution, credential, or `outTrackId` identifiers are recorded.
|
|
54
|
+
|
|
55
|
+
## v0.3.0 stable release — 2026-10-24
|
|
56
|
+
|
|
57
|
+
Stable acceptance for the existing v0.3 scope is closed and the release is published. The earlier beta-era records below are historical; this section records the final stable-release evidence and supersedes their open/remaining v0.3 acceptance statements.
|
|
6
58
|
|
|
7
59
|
On the connected n8n **2.44.5** instance, the following live paths passed:
|
|
8
60
|
|
|
@@ -12,13 +64,24 @@ On the connected n8n **2.44.5** instance, the following live paths passed:
|
|
|
12
64
|
- A newly sent v0.3 interaction card received a real button click through the DingTalk Stream callback. DingTalk Card Trigger emitted the callback and downstream asynchronous Update succeeded; the temporary test listener was then unpublished.
|
|
13
65
|
- A user-performed n8n Community Nodes UI uninstall/reinstall of `0.3.0-beta.1` restored DB/manifest/installed-package version consistency. This is supported lifecycle evidence; no internal database or Community Nodes directory was directly mutated for product acceptance.
|
|
14
66
|
|
|
15
|
-
|
|
67
|
+
This evidence closes the v0.3.0 acceptance scope; it does not certify v1.0 or untested DingTalk templates, form interactions, reconnect and failure modes, or other n8n versions. Stable upgrade remains a user-operated supported Community Nodes UI action. No direct internal database or Community Nodes directory mutation was used as product acceptance.
|
|
68
|
+
|
|
69
|
+
### Public release identity and artifact
|
|
70
|
+
|
|
71
|
+
- Stable tag `v0.3.0` targets release commit `e1510c3b0e48b83d7bea9565c20c3c6ec536d17e`; tag CI run [40105981048](https://github.com/NTLx/n8n-nodes-dingtalk-card/actions/runs/40105981048) succeeded.
|
|
72
|
+
- npm Trusted Publisher/OIDC publish run [40106100176](https://github.com/NTLx/n8n-nodes-dingtalk-card/actions/runs/40106100176), attempt 1, succeeded with provenance. npm `latest` resolves to `0.3.0`; `beta` remains `0.3.0-beta.1`.
|
|
73
|
+
- Public stable GitHub Release: [v0.3.0](https://github.com/NTLx/n8n-nodes-dingtalk-card/releases/tag/v0.3.0), published (`draft=false`, `prerelease=false`), with exactly one asset matching the canonical public npm tarball bytes and digest.
|
|
74
|
+
- Canonical `n8n-nodes-dingtalk-card-0.3.0.tgz`: **48,313 bytes**; SHA-256 `f0776ea697f29cde5b0fe2f7b2b5574f3d029b161ee2a3c348174b1fc3f61972`; SHA-1 `c94da00b74e0af6274796b0e4242f1a457f14f8b`; SHA-512 `f47293ebe7c8c48e23cff5f86e68e3b7cf7dccba1e26c1c59c20ba40f155ba1aea60c153985d814a3f6e40ab43ad62b78f7516f8ea18da89acdc3d56624e8149`; npm integrity `sha512-9HKT6+fIxI4jz/X4bmjjt899zLoeJsHFnCC6QPFVuhrqYMFTmF2BSj9uQKtDrWK3j3UW+OoY2oms3D1WYk6BSQ==`.
|
|
75
|
+
|
|
76
|
+
### Update-discovery evidence
|
|
16
77
|
|
|
17
|
-
|
|
78
|
+
In a disposable `/tmp` package project using `https://registry.npmjs.org/`, `n8n-nodes-dingtalk-card` was installed with an exact `0.3.0-beta.1` dependency and `npm outdated --json` reported `current: 0.3.0-beta.1`, `wanted: 0.3.0-beta.1`, and `latest: 0.3.0`. The temporary project was removed. This confirms npm update discovery exposes stable as the latest version for that pinned beta install. It is not evidence that the n8n Community Nodes UI Update button was clicked or observed, and it did not access production n8n. The stable upgrade remains a user-operated supported Community Nodes UI action.
|
|
18
79
|
|
|
19
|
-
|
|
80
|
+
Local release gates passed on **Node 26.12.1 / npm 12.2.1**: clean `npm ci`; lint; typecheck; build; **56 tests passed / 0 failed / 0 skipped**; `verify:package` including standalone extracted class registration (**20 allowlisted files**); `npm audit --omit=dev --audit-level=high` (**0 production vulnerabilities**); and `git diff --check`. The clean install reports the existing development-tree advisories (**19 high, 4 moderate**), deprecations and five blocked install scripts; install completed successfully. These development advisories are outside the production package audit and were not changed as part of this release. These are prepublication gate results; the final public identity and digest are recorded above.
|
|
20
81
|
|
|
21
|
-
The
|
|
82
|
+
The prepublication `npm pack --ignore-scripts --json` inspection found **20 files** in the candidate tarball (48,024 compressed bytes): package metadata, README, changelog, license, compiled nodes/credential and icons, API/design/roadmap/verification docs, and five examples. The packed manifest version was `0.3.0`; no tests, source files, or unrelated repository files were included. This candidate inspection is historical; public registry metadata, provenance and canonical tarball identity are recorded above.
|
|
83
|
+
|
|
84
|
+
The GitHub CI workflow runs the same install/lint/typecheck/build/test/package/audit gates on Node 24 for branch pushes, pull requests and tags. The npm workflow grants only `id-token: write` for Trusted Publisher/OIDC provenance; no npm token or secret is added. Stable `v0.3.0` publishes with `latest`; beta versions publish with `beta` and may synchronize `latest` only while npm reports no stable version. Tag/version checks are exact. This describes the release process; the completed tag, workflow runs, GitHub Release and npm publication are identified above.
|
|
22
85
|
|
|
23
86
|
## v0.3.0-beta.1 release preparation — local verification (historical)
|
|
24
87
|
|
|
@@ -201,3 +264,8 @@ The maintainer supplied the following successful real DingTalk E2E result for do
|
|
|
201
264
|
This validates the tested request-button callback path and immediate receipt ACK transport with asynchronous downstream execution in practice. It does not certify every template, form submission, reconnect or failure mode, establish exactly-once delivery, or add synchronous local-update ACK support. No measured ACK latency or untested recovery behavior is claimed.
|
|
202
265
|
|
|
203
266
|
Only the non-sensitive result is recorded. No private organization/group/robot/user/workflow/execution identifiers, message IDs, tracking IDs, corp IDs, actual callback values or secrets are included. This closure makes no new live calls and changes only repository documentation and existing GitHub prerelease notes. The annotated tag, tagged source, package version/lockfile, release asset and npm publication remain unchanged; the immutable archive's bundled documentation predates this post-release record.
|
|
267
|
+
# v0.4.0-beta.1 prepublication development verification — 2026-10-25 (historical)
|
|
268
|
+
|
|
269
|
+
This records local verification before publication; its unpublished status describes that point in time only. Current publication and production preflight status is recorded in [the post-release section above](#v040-beta1-publication-and-production-preflight-2026-10-25). The v0.4.0 Presentation Contract & Template Kit was implemented. Package metadata was `0.4.0-beta.1`; release preparation allowed v0.4.0 beta tags under the established beta channel and validated exact package version/tag matches; the stable `v0.3.0` guard remained the only `latest` publish path. On the repository's configured Node/npm environment, release gates passed: clean `npm ci`; `npm run lint`; `npm run typecheck`; `npm run build`; `npm test` (**60 passed, 0 failed**); `npm run verify:package` (standalone packed class loading/registration passed; **27 allowlisted files**); `npm audit --omit=dev --audit-level=high` (**0 production vulnerabilities**); release-ref policy self-tests; YAML and inline Node.js syntax validation; and `git diff --check`. The clean install reported 23 total dependency advisories across development and production dependencies.
|
|
270
|
+
|
|
271
|
+
Tests covered all five descriptor families, deterministic string mapping, contract identity fields, unknown versions/families/fields, wrong types, missing fields, invalid status values, collection bounds, and Create & Deliver/Update node mapping. Existing test coverage remained passing. No DingTalk credentials or live template were used. At prepublication verification time, no template rendering, live acceptance, npm publication, Git tag/release, or external-system mutation was claimed. The package contains no DingTalk platform templates; users must publish templates matching the documented variables.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{
|
|
2
|
+
"descriptor": {"version":"1","family":"action","title":"Review deployment","tone":"warning","label":"Open deployment details","description":"Display metadata only; configure workflow behavior separately."},
|
|
3
|
+
"cardData": {"cardParamMap":{"presentationVersion":"1","presentationFamily":"action","title":"Review deployment","tone":"warning","label":"Open deployment details","description":"Display metadata only; configure workflow behavior separately."}}
|
|
4
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{
|
|
2
|
+
"descriptor": {"version":"1","family":"alert","title":"Disk full","summary":"Storage is above the configured threshold.","tone":"danger","source":"disk-monitor","occurredAt":"2026-10-25T08:30:00Z"},
|
|
3
|
+
"cardData": {"cardParamMap":{"presentationVersion":"1","presentationFamily":"alert","title":"Disk full","summary":"Storage is above the configured threshold.","tone":"danger","source":"disk-monitor","occurredAt":"2026-10-25T08:30:00Z"}}
|
|
4
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{
|
|
2
|
+
"descriptor": {"version":"1","family":"digest","title":"Engineering digest","tone":"neutral","items":[{"title":"Build passed","summary":"Main branch","tone":"success"},{"title":"Deploy pending","tone":"warning"}]},
|
|
3
|
+
"cardData": {"cardParamMap":{"presentationVersion":"1","presentationFamily":"digest","title":"Engineering digest","tone":"neutral","items":"[{\"title\":\"Build passed\",\"summary\":\"Main branch\",\"tone\":\"success\"},{\"title\":\"Deploy pending\",\"tone\":\"warning\"}]"}}
|
|
4
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{
|
|
2
|
+
"descriptor": {"version":"1","family":"report","title":"Daily operations","summary":"Three services checked.","tone":"success","sections":[{"heading":"Availability","body":"All monitored services responded."},{"heading":"Follow-up","body":"Review the weekly maintenance window."}]},
|
|
3
|
+
"cardData": {"cardParamMap":{"presentationVersion":"1","presentationFamily":"report","title":"Daily operations","summary":"Three services checked.","tone":"success","sections":"[{\"heading\":\"Availability\",\"body\":\"All monitored services responded.\"},{\"heading\":\"Follow-up\",\"body\":\"Review the weekly maintenance window.\"}]"}}
|
|
4
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{
|
|
2
|
+
"descriptor": {"version":"1","family":"status","title":"Nightly backup","summary":"Archive upload is running.","tone":"info","state":"running","details":"12 of 40 GB uploaded"},
|
|
3
|
+
"cardData": {"cardParamMap":{"presentationVersion":"1","presentationFamily":"status","title":"Nightly backup","summary":"Archive upload is running.","tone":"info","state":"running","details":"12 of 40 GB uploaded"}}
|
|
4
|
+
}
|
package/package.json
CHANGED