@open-feishu-card/store 0.1.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.
@@ -0,0 +1,22 @@
1
+ /** fragment 协议版本:s1 = JSON → UTF-8 → deflate → base64url */
2
+ export declare const STATE_CODEC_VERSION: 's1';
3
+ /** 跳转基座:即使被点到也不会打开网页 */
4
+ export declare const STATE_URL_BASE = "lark://msgcard/unsupported_action";
5
+ /** 完整 URL 前缀(含 #) */
6
+ export declare const STATE_URL_PREFIX: "lark://msgcard/unsupported_action#";
7
+ export declare class StateCodecError extends Error {
8
+ constructor(message: string);
9
+ }
10
+ /**
11
+ * 把任意 JSON 可序列化值编码为完整封印 URL。
12
+ * 格式:`lark://msgcard/unsupported_action#s1.<base64url(deflate(json))>`
13
+ */
14
+ export declare function encodeStateUrl(state: unknown): string;
15
+ /**
16
+ * 从封印 URL(或裸 fragment / 带版本前缀的 payload)解码 state。
17
+ * 无法识别或损坏时返回 null。
18
+ */
19
+ export declare function decodeStateUrl(urlOrFragment: string): unknown | null;
20
+ /** 判断字符串是否为我们的封印 URL / fragment */
21
+ export declare function isStateUrl(value: string): boolean;
22
+ //# sourceMappingURL=codec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../src/codec.ts"],"names":[],"mappings":"AAEA,4DAA4D;AAC5D,eAAO,MAAM,mBAAmB,EAAG,IAAa,CAAC;AAEjD,wBAAwB;AACxB,eAAO,MAAM,cAAc,sCAAsC,CAAC;AAElE,qBAAqB;AACrB,eAAO,MAAM,gBAAgB,sCAAgC,CAAC;AAE9D,qBAAa,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAerD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CA2BpE;AAED,mCAAmC;AACnC,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAUjD"}
package/dist/host.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ /** 专用空分栏宿主的 element_id(写入时保证;飞书/adapter 回读可能丢掉) */
2
+ export declare const STATE_ELEMENT_ID = "card_state";
3
+ /** 构造专用空分栏宿主(只写 url,避免 4 份复制吃额度) */
4
+ export declare function createStateHost(stateUrl: string): Record<string, unknown>;
5
+ /** 在卡片上查找 state 宿主 column_set */
6
+ export declare function findStateHost(card: Record<string, unknown>): Record<string, unknown> | null;
7
+ /**
8
+ * 从卡片读取封印 state(不改卡)。
9
+ * 兼容:DSL `action.multi_url`、adapter 投影的 `actions[]`、RAW `property.actions`。
10
+ */
11
+ export declare function readCardState<T = unknown>(card: Record<string, unknown>): T | null;
12
+ /**
13
+ * 把 state 封印进卡片:写入/更新空分栏 `card_state` 的 `action.multi_url.url`。
14
+ * 就地修改 card;返回编码后的 URL。
15
+ */
16
+ export declare function sealCardState(card: Record<string, unknown>, state: unknown): string;
17
+ /**
18
+ * 读取并移除宿主分栏(可选,用于迁移)。
19
+ * 返回解码到的 state;没有则 null。
20
+ */
21
+ export declare function unsealCardState<T = unknown>(card: Record<string, unknown>): T | null;
22
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAOA,mDAAmD;AACnD,eAAO,MAAM,gBAAgB,eAAe,CAAC;AA6E7C,oCAAoC;AACpC,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzE;AAgBD,iCAAiC;AACjC,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAO3F;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAkClF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAUnF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAOpF"}
package/dist/index.cjs ADDED
@@ -0,0 +1,221 @@
1
+ 'use strict';
2
+
3
+ var zlib = require('zlib');
4
+
5
+ // src/codec.ts
6
+ var STATE_CODEC_VERSION = "s1";
7
+ var STATE_URL_BASE = "lark://msgcard/unsupported_action";
8
+ var STATE_URL_PREFIX = `${STATE_URL_BASE}#`;
9
+ var StateCodecError = class extends Error {
10
+ constructor(message) {
11
+ super(message);
12
+ this.name = "StateCodecError";
13
+ }
14
+ };
15
+ function encodeStateUrl(state) {
16
+ let json;
17
+ try {
18
+ json = JSON.stringify(state);
19
+ } catch (err) {
20
+ throw new StateCodecError(
21
+ `state \u65E0\u6CD5 JSON \u5E8F\u5217\u5316: ${err instanceof Error ? err.message : String(err)}`
22
+ );
23
+ }
24
+ if (json === void 0) {
25
+ throw new StateCodecError("state \u65E0\u6CD5 JSON \u5E8F\u5217\u5316\uFF08undefined\uFF09");
26
+ }
27
+ const compressed = zlib.deflateSync(Buffer.from(json, "utf8"), { level: 9 });
28
+ const payload = compressed.toString("base64url");
29
+ return `${STATE_URL_PREFIX}${STATE_CODEC_VERSION}.${payload}`;
30
+ }
31
+ function decodeStateUrl(urlOrFragment) {
32
+ if (typeof urlOrFragment !== "string" || !urlOrFragment) return null;
33
+ let fragment = urlOrFragment;
34
+ const hash = urlOrFragment.indexOf("#");
35
+ if (hash >= 0) {
36
+ fragment = urlOrFragment.slice(hash + 1);
37
+ }
38
+ const dot = fragment.indexOf(".");
39
+ if (dot <= 0) return null;
40
+ const version = fragment.slice(0, dot);
41
+ const payload = fragment.slice(dot + 1);
42
+ if (!payload) return null;
43
+ if (version === STATE_CODEC_VERSION) {
44
+ try {
45
+ const raw = Buffer.from(payload, "base64url");
46
+ const json = zlib.inflateSync(raw).toString("utf8");
47
+ return JSON.parse(json);
48
+ } catch {
49
+ return null;
50
+ }
51
+ }
52
+ return null;
53
+ }
54
+ function isStateUrl(value) {
55
+ if (typeof value !== "string" || !value) return false;
56
+ if (value.startsWith(STATE_URL_PREFIX)) {
57
+ return decodeStateUrl(value) !== null;
58
+ }
59
+ if (value.startsWith(`${STATE_CODEC_VERSION}.`)) {
60
+ return decodeStateUrl(value) !== null;
61
+ }
62
+ return false;
63
+ }
64
+
65
+ // src/host.ts
66
+ var STATE_ELEMENT_ID = "card_state";
67
+ function isRecord(value) {
68
+ return typeof value === "object" && value !== null && !Array.isArray(value);
69
+ }
70
+ function walk(node, visit, parent = null) {
71
+ if (Array.isArray(node)) {
72
+ for (const child of node) walk(child, visit, parent);
73
+ return;
74
+ }
75
+ if (!isRecord(node)) return;
76
+ visit(node, parent);
77
+ for (const value of Object.values(node)) walk(value, visit, node);
78
+ }
79
+ function extractStateUrl(node) {
80
+ const action = node.action;
81
+ if (isRecord(action)) {
82
+ const multi = action.multi_url;
83
+ if (isRecord(multi) && typeof multi.url === "string" && isStateUrl(multi.url)) {
84
+ return multi.url;
85
+ }
86
+ if (typeof action.url === "string" && isStateUrl(action.url)) {
87
+ return action.url;
88
+ }
89
+ }
90
+ if (Array.isArray(node.actions)) {
91
+ for (const item of node.actions) {
92
+ if (!isRecord(item)) continue;
93
+ const inner = isRecord(item.action) ? item.action : item;
94
+ for (const key of ["url", "default_url", "pc_url", "ios_url", "android_url", "pcURL", "iosURL", "androidURL"]) {
95
+ const v = inner[key];
96
+ if (typeof v === "string" && isStateUrl(v)) return v;
97
+ }
98
+ }
99
+ }
100
+ const property = node.property;
101
+ if (isRecord(property) && Array.isArray(property.actions)) {
102
+ for (const item of property.actions) {
103
+ if (!isRecord(item)) continue;
104
+ const inner = isRecord(item.action) ? item.action : item;
105
+ for (const key of ["url", "pcURL", "iosURL", "androidURL"]) {
106
+ const v = inner[key];
107
+ if (typeof v === "string" && isStateUrl(v)) return v;
108
+ }
109
+ }
110
+ }
111
+ if (isRecord(node.multi_url) && typeof node.multi_url.url === "string" && isStateUrl(node.multi_url.url)) {
112
+ return node.multi_url.url;
113
+ }
114
+ return null;
115
+ }
116
+ function isStateHost(node) {
117
+ if (node.tag === "column_set" && node.element_id === STATE_ELEMENT_ID) return true;
118
+ if (node.tag === "column_set" && node.id === STATE_ELEMENT_ID) return true;
119
+ if (node.tag === "column_set" && extractStateUrl(node)) return true;
120
+ if (node.id === STATE_ELEMENT_ID && extractStateUrl(node)) return true;
121
+ return false;
122
+ }
123
+ function createStateHost(stateUrl) {
124
+ return {
125
+ tag: "column_set",
126
+ element_id: STATE_ELEMENT_ID,
127
+ action: {
128
+ multi_url: {
129
+ url: stateUrl
130
+ }
131
+ },
132
+ columns: [
133
+ {
134
+ tag: "column",
135
+ width: "auto",
136
+ elements: []
137
+ }
138
+ ]
139
+ };
140
+ }
141
+ function ensureBodyElements(card) {
142
+ const existing = card.body;
143
+ const body = isRecord(existing) ? existing : { elements: [] };
144
+ if (!isRecord(existing)) {
145
+ card.body = body;
146
+ }
147
+ if (!Array.isArray(body.elements)) {
148
+ body.elements = [];
149
+ }
150
+ return body.elements;
151
+ }
152
+ function findStateHost(card) {
153
+ let found = null;
154
+ walk(card, (obj) => {
155
+ if (found) return;
156
+ if (isStateHost(obj)) found = obj;
157
+ });
158
+ return found;
159
+ }
160
+ function readCardState(card) {
161
+ const host = findStateHost(card);
162
+ if (host) {
163
+ const url = extractStateUrl(host);
164
+ if (url) {
165
+ const state = decodeStateUrl(url);
166
+ return state;
167
+ }
168
+ }
169
+ let decoded = null;
170
+ walk(card, (obj) => {
171
+ if (decoded !== null) return;
172
+ const url = extractStateUrl(obj);
173
+ if (url) decoded = decodeStateUrl(url);
174
+ });
175
+ if (decoded === null) {
176
+ walk(card, (obj) => {
177
+ if (decoded !== null) return;
178
+ for (const v of Object.values(obj)) {
179
+ if (typeof v === "string" && v.startsWith(STATE_URL_PREFIX)) {
180
+ const s = decodeStateUrl(v);
181
+ if (s !== null) {
182
+ decoded = s;
183
+ return;
184
+ }
185
+ }
186
+ }
187
+ });
188
+ }
189
+ return decoded;
190
+ }
191
+ function sealCardState(card, state) {
192
+ const stateUrl = encodeStateUrl(state);
193
+ const elements = ensureBodyElements(card);
194
+ const next = elements.filter((el) => !(isRecord(el) && isStateHost(el)));
195
+ next.push(createStateHost(stateUrl));
196
+ const body = card.body;
197
+ body.elements = next;
198
+ return stateUrl;
199
+ }
200
+ function unsealCardState(card) {
201
+ const state = readCardState(card);
202
+ const body = isRecord(card.body) ? card.body : null;
203
+ if (body && Array.isArray(body.elements)) {
204
+ body.elements = body.elements.filter((el) => !(isRecord(el) && isStateHost(el)));
205
+ }
206
+ return state;
207
+ }
208
+
209
+ exports.STATE_CODEC_VERSION = STATE_CODEC_VERSION;
210
+ exports.STATE_ELEMENT_ID = STATE_ELEMENT_ID;
211
+ exports.STATE_URL_BASE = STATE_URL_BASE;
212
+ exports.STATE_URL_PREFIX = STATE_URL_PREFIX;
213
+ exports.StateCodecError = StateCodecError;
214
+ exports.createStateHost = createStateHost;
215
+ exports.decodeStateUrl = decodeStateUrl;
216
+ exports.encodeStateUrl = encodeStateUrl;
217
+ exports.findStateHost = findStateHost;
218
+ exports.isStateUrl = isStateUrl;
219
+ exports.readCardState = readCardState;
220
+ exports.sealCardState = sealCardState;
221
+ exports.unsealCardState = unsealCardState;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @open-feishu-card/store
3
+ *
4
+ * 卡片内嵌 state:空 `column_set`(零高度)+ `action.multi_url.url`,
5
+ * 载荷为 `deflate → base64url`。
6
+ *
7
+ * 写入形态(DSL):
8
+ * ```json
9
+ * {
10
+ * "tag": "column_set",
11
+ * "element_id": "card_state",
12
+ * "action": { "multi_url": { "url": "lark://msgcard/unsupported_action#s1...." } },
13
+ * "columns": [{ "tag": "column", "width": "auto", "elements": [] }]
14
+ * }
15
+ * ```
16
+ *
17
+ * 回读请走 `raw_card_content`(`user_card_content` 会丢掉 URL)。
18
+ */
19
+ export { STATE_CODEC_VERSION, STATE_URL_BASE, STATE_URL_PREFIX, StateCodecError, encodeStateUrl, decodeStateUrl, isStateUrl, } from './codec.js';
20
+ export { STATE_ELEMENT_ID, createStateHost, findStateHost, readCardState, sealCardState, unsealCardState, } from './host.js';
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,cAAc,EACd,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAAa,EACb,eAAe,GAChB,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,207 @@
1
+ import { deflateSync, inflateSync } from 'zlib';
2
+
3
+ // src/codec.ts
4
+ var STATE_CODEC_VERSION = "s1";
5
+ var STATE_URL_BASE = "lark://msgcard/unsupported_action";
6
+ var STATE_URL_PREFIX = `${STATE_URL_BASE}#`;
7
+ var StateCodecError = class extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "StateCodecError";
11
+ }
12
+ };
13
+ function encodeStateUrl(state) {
14
+ let json;
15
+ try {
16
+ json = JSON.stringify(state);
17
+ } catch (err) {
18
+ throw new StateCodecError(
19
+ `state \u65E0\u6CD5 JSON \u5E8F\u5217\u5316: ${err instanceof Error ? err.message : String(err)}`
20
+ );
21
+ }
22
+ if (json === void 0) {
23
+ throw new StateCodecError("state \u65E0\u6CD5 JSON \u5E8F\u5217\u5316\uFF08undefined\uFF09");
24
+ }
25
+ const compressed = deflateSync(Buffer.from(json, "utf8"), { level: 9 });
26
+ const payload = compressed.toString("base64url");
27
+ return `${STATE_URL_PREFIX}${STATE_CODEC_VERSION}.${payload}`;
28
+ }
29
+ function decodeStateUrl(urlOrFragment) {
30
+ if (typeof urlOrFragment !== "string" || !urlOrFragment) return null;
31
+ let fragment = urlOrFragment;
32
+ const hash = urlOrFragment.indexOf("#");
33
+ if (hash >= 0) {
34
+ fragment = urlOrFragment.slice(hash + 1);
35
+ }
36
+ const dot = fragment.indexOf(".");
37
+ if (dot <= 0) return null;
38
+ const version = fragment.slice(0, dot);
39
+ const payload = fragment.slice(dot + 1);
40
+ if (!payload) return null;
41
+ if (version === STATE_CODEC_VERSION) {
42
+ try {
43
+ const raw = Buffer.from(payload, "base64url");
44
+ const json = inflateSync(raw).toString("utf8");
45
+ return JSON.parse(json);
46
+ } catch {
47
+ return null;
48
+ }
49
+ }
50
+ return null;
51
+ }
52
+ function isStateUrl(value) {
53
+ if (typeof value !== "string" || !value) return false;
54
+ if (value.startsWith(STATE_URL_PREFIX)) {
55
+ return decodeStateUrl(value) !== null;
56
+ }
57
+ if (value.startsWith(`${STATE_CODEC_VERSION}.`)) {
58
+ return decodeStateUrl(value) !== null;
59
+ }
60
+ return false;
61
+ }
62
+
63
+ // src/host.ts
64
+ var STATE_ELEMENT_ID = "card_state";
65
+ function isRecord(value) {
66
+ return typeof value === "object" && value !== null && !Array.isArray(value);
67
+ }
68
+ function walk(node, visit, parent = null) {
69
+ if (Array.isArray(node)) {
70
+ for (const child of node) walk(child, visit, parent);
71
+ return;
72
+ }
73
+ if (!isRecord(node)) return;
74
+ visit(node, parent);
75
+ for (const value of Object.values(node)) walk(value, visit, node);
76
+ }
77
+ function extractStateUrl(node) {
78
+ const action = node.action;
79
+ if (isRecord(action)) {
80
+ const multi = action.multi_url;
81
+ if (isRecord(multi) && typeof multi.url === "string" && isStateUrl(multi.url)) {
82
+ return multi.url;
83
+ }
84
+ if (typeof action.url === "string" && isStateUrl(action.url)) {
85
+ return action.url;
86
+ }
87
+ }
88
+ if (Array.isArray(node.actions)) {
89
+ for (const item of node.actions) {
90
+ if (!isRecord(item)) continue;
91
+ const inner = isRecord(item.action) ? item.action : item;
92
+ for (const key of ["url", "default_url", "pc_url", "ios_url", "android_url", "pcURL", "iosURL", "androidURL"]) {
93
+ const v = inner[key];
94
+ if (typeof v === "string" && isStateUrl(v)) return v;
95
+ }
96
+ }
97
+ }
98
+ const property = node.property;
99
+ if (isRecord(property) && Array.isArray(property.actions)) {
100
+ for (const item of property.actions) {
101
+ if (!isRecord(item)) continue;
102
+ const inner = isRecord(item.action) ? item.action : item;
103
+ for (const key of ["url", "pcURL", "iosURL", "androidURL"]) {
104
+ const v = inner[key];
105
+ if (typeof v === "string" && isStateUrl(v)) return v;
106
+ }
107
+ }
108
+ }
109
+ if (isRecord(node.multi_url) && typeof node.multi_url.url === "string" && isStateUrl(node.multi_url.url)) {
110
+ return node.multi_url.url;
111
+ }
112
+ return null;
113
+ }
114
+ function isStateHost(node) {
115
+ if (node.tag === "column_set" && node.element_id === STATE_ELEMENT_ID) return true;
116
+ if (node.tag === "column_set" && node.id === STATE_ELEMENT_ID) return true;
117
+ if (node.tag === "column_set" && extractStateUrl(node)) return true;
118
+ if (node.id === STATE_ELEMENT_ID && extractStateUrl(node)) return true;
119
+ return false;
120
+ }
121
+ function createStateHost(stateUrl) {
122
+ return {
123
+ tag: "column_set",
124
+ element_id: STATE_ELEMENT_ID,
125
+ action: {
126
+ multi_url: {
127
+ url: stateUrl
128
+ }
129
+ },
130
+ columns: [
131
+ {
132
+ tag: "column",
133
+ width: "auto",
134
+ elements: []
135
+ }
136
+ ]
137
+ };
138
+ }
139
+ function ensureBodyElements(card) {
140
+ const existing = card.body;
141
+ const body = isRecord(existing) ? existing : { elements: [] };
142
+ if (!isRecord(existing)) {
143
+ card.body = body;
144
+ }
145
+ if (!Array.isArray(body.elements)) {
146
+ body.elements = [];
147
+ }
148
+ return body.elements;
149
+ }
150
+ function findStateHost(card) {
151
+ let found = null;
152
+ walk(card, (obj) => {
153
+ if (found) return;
154
+ if (isStateHost(obj)) found = obj;
155
+ });
156
+ return found;
157
+ }
158
+ function readCardState(card) {
159
+ const host = findStateHost(card);
160
+ if (host) {
161
+ const url = extractStateUrl(host);
162
+ if (url) {
163
+ const state = decodeStateUrl(url);
164
+ return state;
165
+ }
166
+ }
167
+ let decoded = null;
168
+ walk(card, (obj) => {
169
+ if (decoded !== null) return;
170
+ const url = extractStateUrl(obj);
171
+ if (url) decoded = decodeStateUrl(url);
172
+ });
173
+ if (decoded === null) {
174
+ walk(card, (obj) => {
175
+ if (decoded !== null) return;
176
+ for (const v of Object.values(obj)) {
177
+ if (typeof v === "string" && v.startsWith(STATE_URL_PREFIX)) {
178
+ const s = decodeStateUrl(v);
179
+ if (s !== null) {
180
+ decoded = s;
181
+ return;
182
+ }
183
+ }
184
+ }
185
+ });
186
+ }
187
+ return decoded;
188
+ }
189
+ function sealCardState(card, state) {
190
+ const stateUrl = encodeStateUrl(state);
191
+ const elements = ensureBodyElements(card);
192
+ const next = elements.filter((el) => !(isRecord(el) && isStateHost(el)));
193
+ next.push(createStateHost(stateUrl));
194
+ const body = card.body;
195
+ body.elements = next;
196
+ return stateUrl;
197
+ }
198
+ function unsealCardState(card) {
199
+ const state = readCardState(card);
200
+ const body = isRecord(card.body) ? card.body : null;
201
+ if (body && Array.isArray(body.elements)) {
202
+ body.elements = body.elements.filter((el) => !(isRecord(el) && isStateHost(el)));
203
+ }
204
+ return state;
205
+ }
206
+
207
+ export { STATE_CODEC_VERSION, STATE_ELEMENT_ID, STATE_URL_BASE, STATE_URL_PREFIX, StateCodecError, createStateHost, decodeStateUrl, encodeStateUrl, findStateHost, isStateUrl, readCardState, sealCardState, unsealCardState };
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@open-feishu-card/store",
3
+ "version": "0.1.0",
4
+ "description": "把卡片运行时 state 封印进空分栏 action.multi_url(deflate + base64url),支持 DSL / RAW 回读",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup && tsc -p tsconfig.json --emitDeclarationOnly",
21
+ "typecheck": "tsc --noEmit -p tsconfig.json",
22
+ "test": "tsx --test test/*.test.ts"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^22.20.1",
26
+ "tsup": "^8.3.5",
27
+ "tsx": "^4.19.3",
28
+ "typescript": "^7.0.2"
29
+ },
30
+ "license": "MIT",
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/ztxtxwd/open-feishu-card-monorepo.git",
37
+ "directory": "packages/store"
38
+ }
39
+ }