@mdbase-dev/pickle 0.1.0-beta.76 → 0.1.0-beta.77

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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type CollectionContractDescriptor, type CollectionDescription, type CollectionTypeDescriptor, type JsonObject, type RecordDocument, type ConnectRequestOptions, type MdbaseConnection, type PendingMutation } from "@mdbase-dev/connect";
2
- export { PICKLE_ACK_RESPONSE_TYPE_DOCUMENT, PICKLE_APPROVAL_RESPONSE_TYPE_DOCUMENT, PICKLE_REQUEST_CONTRACT_DOCUMENT, PICKLE_REQUEST_CONTRACT_DIGEST, PICKLE_TYPE_PACK_PROVISION, PICKLE_REQUEST_TYPE_DOCUMENT } from "./resources.js";
2
+ export { PICKLE_ACK_RESPONSE_TYPE_DOCUMENT, PICKLE_ATTACHMENT_TYPE_DOCUMENT, PICKLE_APPROVAL_RESPONSE_TYPE_DOCUMENT, PICKLE_REQUEST_CONTRACT_DOCUMENT, PICKLE_REQUEST_CONTRACT_DIGEST, PICKLE_TYPE_PACK_PROVISION, PICKLE_REQUEST_TYPE_DOCUMENT } from "./resources.js";
3
3
  export declare const PICKLE_REQUEST_CONTRACT = "pickle.request";
4
4
  export declare const PICKLE_REQUEST_CONTRACT_VERSION = "1.0.0";
5
5
  export declare const PICKLE_NOTIFICATION_CRITERION = "pickle.request.created";
@@ -46,6 +46,13 @@ export interface PickleAttachment {
46
46
  path: string;
47
47
  filename: string;
48
48
  }
49
+ export interface PickleAttachmentContent {
50
+ path: string;
51
+ filename: string;
52
+ mediaType: string;
53
+ size: number;
54
+ blob: Blob;
55
+ }
49
56
  export interface PickleResponse {
50
57
  path: string;
51
58
  type: string;
@@ -92,6 +99,8 @@ export interface PickleClient {
92
99
  describe(options?: ConnectRequestOptions): ReturnType<MdbaseConnection<PickleFrontmatter>["describe"]>;
93
100
  queryAll(input: Parameters<MdbaseConnection<PickleFrontmatter>["queryAll"]>[0], options?: Parameters<MdbaseConnection<PickleFrontmatter>["queryAll"]>[1]): ReturnType<MdbaseConnection<PickleFrontmatter>["queryAll"]>;
94
101
  create(input: Parameters<MdbaseConnection<PickleFrontmatter>["create"]>[0], options?: ConnectRequestOptions): ReturnType<MdbaseConnection<PickleFrontmatter>["create"]>;
102
+ read(input: Parameters<MdbaseConnection<PickleFrontmatter>["read"]>[0], options?: ConnectRequestOptions): ReturnType<MdbaseConnection<PickleFrontmatter>["read"]>;
103
+ files: MdbaseConnection<PickleFrontmatter>["files"];
95
104
  pendingMutations<Result = unknown>(): readonly PendingMutation<Result>[];
96
105
  pendingMutation<Result = unknown>(requestId: string): PendingMutation<Result> | null;
97
106
  }
@@ -111,6 +120,7 @@ export declare class PickleCollection {
111
120
  }>;
112
121
  list(options?: ConnectRequestOptions): Promise<PickleRequest[]>;
113
122
  respond(request: PickleRequest, payload: JsonObject, options?: RespondOptions): Promise<PickleResponseSubmission>;
123
+ readAttachment(attachment: PickleAttachment, options?: ConnectRequestOptions): Promise<PickleAttachmentContent | null>;
114
124
  pendingResponses(): readonly PicklePendingResponse[];
115
125
  recoverResponse(requestId: string, options?: ConnectRequestOptions): Promise<PickleResponseSubmission>;
116
126
  }
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { MDBASE_RECORD_CREATED_CONTRACT, MdbaseConnectError } from "@mdbase-dev/connect";
2
2
  import { PICKLE_REQUEST_CONTRACT_DIGEST } from "./resources.js";
3
- export { PICKLE_ACK_RESPONSE_TYPE_DOCUMENT, PICKLE_APPROVAL_RESPONSE_TYPE_DOCUMENT, PICKLE_REQUEST_CONTRACT_DOCUMENT, PICKLE_REQUEST_CONTRACT_DIGEST, PICKLE_TYPE_PACK_PROVISION, PICKLE_REQUEST_TYPE_DOCUMENT } from "./resources.js";
3
+ export { PICKLE_ACK_RESPONSE_TYPE_DOCUMENT, PICKLE_ATTACHMENT_TYPE_DOCUMENT, PICKLE_APPROVAL_RESPONSE_TYPE_DOCUMENT, PICKLE_REQUEST_CONTRACT_DOCUMENT, PICKLE_REQUEST_CONTRACT_DIGEST, PICKLE_TYPE_PACK_PROVISION, PICKLE_REQUEST_TYPE_DOCUMENT } from "./resources.js";
4
4
  export const PICKLE_REQUEST_CONTRACT = "pickle.request";
5
5
  export const PICKLE_REQUEST_CONTRACT_VERSION = "1.0.0";
6
6
  export const PICKLE_NOTIFICATION_CRITERION = "pickle.request.created";
@@ -105,6 +105,49 @@ export class PickleCollection {
105
105
  }, requestOptions);
106
106
  return responseSubmission(created);
107
107
  }
108
+ async readAttachment(attachment, options = {}) {
109
+ const path = attachment.path.replace(/^\/+/, "");
110
+ if (isMarkdownPath(path)) {
111
+ const outcome = await this.connect.read({ path }, options);
112
+ if (outcome.ok) {
113
+ const frontmatter = outcome.value.frontmatter;
114
+ if (stringField(frontmatter, "type") === "pickle_attachment") {
115
+ const body = outcome.value.body ?? "";
116
+ const filename = stringField(frontmatter, "filename") || attachment.filename;
117
+ const mediaType = stringField(frontmatter, "content_type") || "text/markdown";
118
+ return {
119
+ path,
120
+ filename,
121
+ mediaType,
122
+ size: new TextEncoder().encode(body).byteLength,
123
+ blob: new Blob([body], { type: mediaType })
124
+ };
125
+ }
126
+ }
127
+ }
128
+ const separator = path.lastIndexOf("/");
129
+ const folder = separator < 0 ? undefined : path.slice(0, separator);
130
+ let match = null;
131
+ for await (const file of this.connect.files.list({
132
+ ...options,
133
+ ...(folder ? { folder } : {})
134
+ })) {
135
+ if (file.path === path) {
136
+ match = file;
137
+ break;
138
+ }
139
+ }
140
+ if (!match)
141
+ return null;
142
+ const blob = await this.connect.files.download(match, options);
143
+ return {
144
+ path,
145
+ filename: attachment.filename,
146
+ mediaType: match.mediaType || blob.type || "application/octet-stream",
147
+ size: match.size,
148
+ blob
149
+ };
150
+ }
108
151
  pendingResponses() {
109
152
  return this.connect
110
153
  .pendingMutations()
@@ -291,6 +334,9 @@ function validFieldPath(value) {
291
334
  function trimSlashes(value) {
292
335
  return value.replace(/^\/+|\/+$/g, "");
293
336
  }
337
+ function isMarkdownPath(path) {
338
+ return /\.(?:md|markdown|mdown|mkd|mkdn)$/i.test(path);
339
+ }
294
340
  function asObject(value) {
295
341
  return value !== null && typeof value === "object" && !Array.isArray(value)
296
342
  ? value
@@ -4,11 +4,12 @@ export declare const PICKLE_REQUEST_CONTRACT_DIGEST = "sha256:5a96bbda301de6ec2f
4
4
  export declare const PICKLE_REQUEST_TYPE_DOCUMENT = "---\nkind: mdbase.type\nname: pickle_request\nversion: 1\ndescription: Async request that needs a human response.\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: \"https://json-schema.org/draft/2020-12/schema\"\n type: object\n additionalProperties: true\n required: [title, response_type]\n properties:\n type: { const: pickle_request }\n id: { type: string }\n title: { type: string, minLength: 1 }\n source: { type: string }\n message: { type: string }\n kind: { enum: [approval, choice, input, notice, message] }\n status:\n enum: [pending, answered, cancelled]\n description: Legacy lifecycle marker. Response links are authoritative for answered state.\n priority: { enum: [low, normal, high, urgent] }\n response_type: { type: string }\n created_at: { type: string, format: date-time }\n due_at: { type: string, format: date-time }\n dedupe_key: { type: string }\n tags:\n type: array\n items: { type: string }\n links:\n type: array\n items:\n type: object\n additionalProperties: false\n properties:\n label: { type: string }\n url: { type: string }\n path: { type: string }\n attachment_paths:\n type: array\n items: { type: string }\n metadata:\n type: object\n additionalProperties: true\n context:\n type: object\n additionalProperties: false\n properties:\n cwd: { type: string }\n repo: { type: string }\n task: { type: string }\ncollection:\n display:\n name_field: title\n unique:\n - field: id\n scope: collection\nlifecycle:\n on_create:\n set:\n created_at: { now: true }\nimplements:\n - contract: pickle.request\n version: 1.0.0\n fields:\n id: id\n title: title\n source: source\n message: message\n kind: kind\n status: status\n priority: priority\n response_type: response_type\n created_at: created_at\n tags: tags\n links: links\n attachment_paths: attachment_paths\n metadata: metadata\n---\n";
5
5
  export declare const PICKLE_APPROVAL_RESPONSE_TYPE_DOCUMENT = "---\nkind: mdbase.type\nname: pickle_response_approval\nversion: 1\ndescription: Approve, reject, or request revision for a Pickle request.\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: \"https://json-schema.org/draft/2020-12/schema\"\n type: object\n additionalProperties: true\n required: [request, decision]\n properties:\n type: { const: pickle_response_approval }\n id: { type: string }\n request: { type: string }\n decision: { enum: [approve, reject, revise] }\n comment: { type: string }\n responded_at: { type: string, format: date-time }\n responder: { type: string }\n attachment_paths:\n type: array\n items: { type: string }\ncollection:\n display:\n name_field: decision\n links:\n request:\n target_type: pickle_request\n validate_exists: true\n unique:\n - field: id\n scope: collection\nlifecycle:\n on_create:\n set:\n id: { ulid: true }\n responded_at: { now: true }\n---\n";
6
6
  export declare const PICKLE_ACK_RESPONSE_TYPE_DOCUMENT = "---\nkind: mdbase.type\nname: pickle_response_ack\nversion: 1\ndescription: Acknowledge that a Pickle message was read.\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: \"https://json-schema.org/draft/2020-12/schema\"\n type: object\n additionalProperties: true\n required: [request]\n properties:\n type: { const: pickle_response_ack }\n id: { type: string }\n request: { type: string }\n message: { type: string }\n responded_at: { type: string, format: date-time }\n responder: { type: string }\n attachment_paths:\n type: array\n items: { type: string }\ncollection:\n display:\n name_field: message\n links:\n request:\n target_type: pickle_request\n validate_exists: true\n unique:\n - field: id\n scope: collection\nlifecycle:\n on_create:\n set:\n id: { ulid: true }\n responded_at: { now: true }\n---\n";
7
+ export declare const PICKLE_ATTACHMENT_TYPE_DOCUMENT = "---\nkind: mdbase.type\nname: pickle_attachment\nversion: 1\ndescription: Markdown content attached to a Pickle request.\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: \"https://json-schema.org/draft/2020-12/schema\"\n type: object\n additionalProperties: true\n required: [request_id, filename, content_type, size_bytes, sha256]\n properties:\n type: { const: pickle_attachment }\n request_id: { type: string, minLength: 1 }\n filename: { type: string, minLength: 1 }\n content_type: { type: string, minLength: 1 }\n size_bytes: { type: integer, minimum: 0 }\n sha256: { type: string, pattern: '^sha256:[0-9a-f]{64}$' }\n created_at: { type: string, format: date-time }\ncollection:\n display:\n name_field: filename\n---\n";
7
8
  export declare const PICKLE_TYPE_PACK_PROVISION: {
8
9
  readonly manifest: {
9
10
  readonly kind: "mdbase.type-pack";
10
11
  readonly id: "pickle.requests";
11
- readonly version: "1.0.0";
12
+ readonly version: "1.1.0";
12
13
  readonly name: "Pickle requests";
13
14
  readonly description: "Pickle request and response record types.";
14
15
  readonly resources: readonly [{
@@ -35,6 +36,12 @@ export declare const PICKLE_TYPE_PACK_PROVISION: {
35
36
  readonly source: "types/pickle_response_ack.md";
36
37
  readonly target: "_types/pickle_response_ack.md";
37
38
  readonly digest: "sha256:2530c8d21bb711889f20e0d096045cb6c9a7618583b1e2afff7ada72367de41f";
39
+ }, {
40
+ readonly kind: "type";
41
+ readonly mode: "seed";
42
+ readonly source: "types/pickle_attachment.md";
43
+ readonly target: "_types/pickle_attachment.md";
44
+ readonly digest: "sha256:67f14eeee2c126e99d8b37b7508fa148955b924367e2d2941b1793d1c814ec25";
38
45
  }];
39
46
  };
40
47
  readonly resources: readonly [{
@@ -49,6 +56,9 @@ export declare const PICKLE_TYPE_PACK_PROVISION: {
49
56
  }, {
50
57
  readonly source: "types/pickle_response_ack.md";
51
58
  readonly document: "---\nkind: mdbase.type\nname: pickle_response_ack\nversion: 1\ndescription: Acknowledge that a Pickle message was read.\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: \"https://json-schema.org/draft/2020-12/schema\"\n type: object\n additionalProperties: true\n required: [request]\n properties:\n type: { const: pickle_response_ack }\n id: { type: string }\n request: { type: string }\n message: { type: string }\n responded_at: { type: string, format: date-time }\n responder: { type: string }\n attachment_paths:\n type: array\n items: { type: string }\ncollection:\n display:\n name_field: message\n links:\n request:\n target_type: pickle_request\n validate_exists: true\n unique:\n - field: id\n scope: collection\nlifecycle:\n on_create:\n set:\n id: { ulid: true }\n responded_at: { now: true }\n---\n";
59
+ }, {
60
+ readonly source: "types/pickle_attachment.md";
61
+ readonly document: "---\nkind: mdbase.type\nname: pickle_attachment\nversion: 1\ndescription: Markdown content attached to a Pickle request.\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: \"https://json-schema.org/draft/2020-12/schema\"\n type: object\n additionalProperties: true\n required: [request_id, filename, content_type, size_bytes, sha256]\n properties:\n type: { const: pickle_attachment }\n request_id: { type: string, minLength: 1 }\n filename: { type: string, minLength: 1 }\n content_type: { type: string, minLength: 1 }\n size_bytes: { type: integer, minimum: 0 }\n sha256: { type: string, pattern: '^sha256:[0-9a-f]{64}$' }\n created_at: { type: string, format: date-time }\ncollection:\n display:\n name_field: filename\n---\n";
52
62
  }];
53
63
  readonly provides: readonly [{
54
64
  readonly id: "pickle.request";
package/dist/resources.js CHANGED
@@ -204,11 +204,36 @@ lifecycle:
204
204
  responded_at: { now: true }
205
205
  ---
206
206
  `;
207
+ export const PICKLE_ATTACHMENT_TYPE_DOCUMENT = `---
208
+ kind: mdbase.type
209
+ name: pickle_attachment
210
+ version: 1
211
+ description: Markdown content attached to a Pickle request.
212
+ schema:
213
+ dialect: json-schema-2020-12
214
+ value:
215
+ $schema: "https://json-schema.org/draft/2020-12/schema"
216
+ type: object
217
+ additionalProperties: true
218
+ required: [request_id, filename, content_type, size_bytes, sha256]
219
+ properties:
220
+ type: { const: pickle_attachment }
221
+ request_id: { type: string, minLength: 1 }
222
+ filename: { type: string, minLength: 1 }
223
+ content_type: { type: string, minLength: 1 }
224
+ size_bytes: { type: integer, minimum: 0 }
225
+ sha256: { type: string, pattern: '^sha256:[0-9a-f]{64}$' }
226
+ created_at: { type: string, format: date-time }
227
+ collection:
228
+ display:
229
+ name_field: filename
230
+ ---
231
+ `;
207
232
  export const PICKLE_TYPE_PACK_PROVISION = {
208
233
  manifest: {
209
234
  kind: "mdbase.type-pack",
210
235
  id: "pickle.requests",
211
- version: "1.0.0",
236
+ version: "1.1.0",
212
237
  name: "Pickle requests",
213
238
  description: "Pickle request and response record types.",
214
239
  resources: [
@@ -239,6 +264,13 @@ export const PICKLE_TYPE_PACK_PROVISION = {
239
264
  source: "types/pickle_response_ack.md",
240
265
  target: "_types/pickle_response_ack.md",
241
266
  digest: "sha256:2530c8d21bb711889f20e0d096045cb6c9a7618583b1e2afff7ada72367de41f"
267
+ },
268
+ {
269
+ kind: "type",
270
+ mode: "seed",
271
+ source: "types/pickle_attachment.md",
272
+ target: "_types/pickle_attachment.md",
273
+ digest: "sha256:67f14eeee2c126e99d8b37b7508fa148955b924367e2d2941b1793d1c814ec25"
242
274
  }
243
275
  ]
244
276
  },
@@ -258,6 +290,10 @@ export const PICKLE_TYPE_PACK_PROVISION = {
258
290
  {
259
291
  source: "types/pickle_response_ack.md",
260
292
  document: PICKLE_ACK_RESPONSE_TYPE_DOCUMENT
293
+ },
294
+ {
295
+ source: "types/pickle_attachment.md",
296
+ document: PICKLE_ATTACHMENT_TYPE_DOCUMENT
261
297
  }
262
298
  ],
263
299
  provides: [{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mdbase-dev/pickle",
3
- "version": "0.1.0-beta.76",
3
+ "version": "0.1.0-beta.77",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -22,13 +22,13 @@
22
22
  "README.md"
23
23
  ],
24
24
  "dependencies": {
25
- "@mdbase-dev/connect": "0.1.0-beta.76"
25
+ "@mdbase-dev/connect": "0.1.0-beta.77"
26
26
  },
27
27
  "devDependencies": {
28
28
  "typescript": "^7.0.2",
29
29
  "vitest": "^4.1.10",
30
- "@mdbase-dev/connect-dev": "0.1.0-beta.76",
31
- "@mdbase-dev/connect-testing": "0.1.0-beta.76"
30
+ "@mdbase-dev/connect-dev": "0.1.0-beta.77",
31
+ "@mdbase-dev/connect-testing": "0.1.0-beta.77"
32
32
  },
33
33
  "scripts": {
34
34
  "build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json",