spectrum-ts 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-UZWRB3FZ.js +624 -0
- package/dist/chunk-XZTTLPHE.js +341 -0
- package/dist/index.d.ts +137 -5
- package/dist/index.js +158 -79
- package/dist/providers/imessage/index.d.ts +1 -1
- package/dist/providers/imessage/index.js +369 -69
- package/dist/providers/terminal/index.d.ts +1 -1
- package/dist/providers/terminal/index.js +7 -3
- package/dist/providers/whatsapp-business/index.d.ts +1 -1
- package/dist/providers/whatsapp-business/index.js +289 -35
- package/dist/{types-BdWMydUJ.d.ts → types-DZMHfgYQ.d.ts} +102 -13
- package/package.json +9 -2
- package/dist/chunk-5XW4CAWS.js +0 -165
- package/dist/chunk-XEEDIGVK.js +0 -199
package/dist/chunk-5XW4CAWS.js
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
// src/content/attachment.ts
|
|
2
|
-
import { createReadStream } from "fs";
|
|
3
|
-
import { readFile, stat } from "fs/promises";
|
|
4
|
-
import { basename } from "path";
|
|
5
|
-
import { Readable } from "stream";
|
|
6
|
-
import { lookup as lookupMimeType } from "mime-types";
|
|
7
|
-
import z from "zod";
|
|
8
|
-
var DEFAULT_ATTACHMENT_NAME = "attachment";
|
|
9
|
-
var readSchema = z.function({
|
|
10
|
-
input: [],
|
|
11
|
-
output: z.promise(z.instanceof(Buffer))
|
|
12
|
-
});
|
|
13
|
-
var streamSchema = z.function({
|
|
14
|
-
input: [],
|
|
15
|
-
output: z.promise(z.instanceof(ReadableStream))
|
|
16
|
-
});
|
|
17
|
-
var attachmentSchema = z.object({
|
|
18
|
-
type: z.literal("attachment"),
|
|
19
|
-
name: z.string().nonempty(),
|
|
20
|
-
mimeType: z.string().nonempty(),
|
|
21
|
-
size: z.number().int().nonnegative().optional(),
|
|
22
|
-
read: readSchema,
|
|
23
|
-
stream: streamSchema
|
|
24
|
-
});
|
|
25
|
-
var resolveAttachmentName = (input, name) => name || (typeof input === "string" ? basename(input) : DEFAULT_ATTACHMENT_NAME);
|
|
26
|
-
var resolveAttachmentMimeType = (name, mimeType) => {
|
|
27
|
-
if (mimeType) {
|
|
28
|
-
return mimeType;
|
|
29
|
-
}
|
|
30
|
-
const resolvedMimeType = lookupMimeType(name);
|
|
31
|
-
if (!resolvedMimeType) {
|
|
32
|
-
throw new Error(
|
|
33
|
-
`Unable to resolve MIME type for attachment "${name}". Pass options.mimeType explicitly.`
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
return resolvedMimeType;
|
|
37
|
-
};
|
|
38
|
-
var bufferToStream = (buf) => new ReadableStream({
|
|
39
|
-
start(controller) {
|
|
40
|
-
controller.enqueue(buf);
|
|
41
|
-
controller.close();
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
var asAttachment = (input) => {
|
|
45
|
-
let cached;
|
|
46
|
-
const read = () => {
|
|
47
|
-
cached ??= input.read().catch((err) => {
|
|
48
|
-
cached = void 0;
|
|
49
|
-
throw err;
|
|
50
|
-
});
|
|
51
|
-
return cached;
|
|
52
|
-
};
|
|
53
|
-
const stream2 = input.stream ?? (async () => bufferToStream(await read()));
|
|
54
|
-
return attachmentSchema.parse({
|
|
55
|
-
type: "attachment",
|
|
56
|
-
name: input.name,
|
|
57
|
-
mimeType: input.mimeType,
|
|
58
|
-
size: input.size,
|
|
59
|
-
read,
|
|
60
|
-
stream: stream2
|
|
61
|
-
});
|
|
62
|
-
};
|
|
63
|
-
function attachment(input, options) {
|
|
64
|
-
return {
|
|
65
|
-
build: async () => {
|
|
66
|
-
const name = resolveAttachmentName(input, options?.name);
|
|
67
|
-
const mimeType = resolveAttachmentMimeType(name, options?.mimeType);
|
|
68
|
-
if (typeof input === "string") {
|
|
69
|
-
const stats = await stat(input);
|
|
70
|
-
return asAttachment({
|
|
71
|
-
name,
|
|
72
|
-
mimeType,
|
|
73
|
-
size: stats.size,
|
|
74
|
-
read: () => readFile(input),
|
|
75
|
-
stream: async () => Readable.toWeb(
|
|
76
|
-
createReadStream(input)
|
|
77
|
-
)
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
return asAttachment({
|
|
81
|
-
name,
|
|
82
|
-
mimeType,
|
|
83
|
-
size: input.byteLength,
|
|
84
|
-
read: async () => input,
|
|
85
|
-
stream: async () => bufferToStream(input)
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// src/content/custom.ts
|
|
92
|
-
import z2 from "zod";
|
|
93
|
-
var customSchema = z2.object({
|
|
94
|
-
type: z2.literal("custom"),
|
|
95
|
-
raw: z2.unknown()
|
|
96
|
-
});
|
|
97
|
-
var asCustom = (raw) => customSchema.parse({ type: "custom", raw });
|
|
98
|
-
function custom(raw) {
|
|
99
|
-
return {
|
|
100
|
-
build: async () => asCustom(raw)
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// src/utils/stream.ts
|
|
105
|
-
import { Repeater } from "@repeaterjs/repeater";
|
|
106
|
-
function stream(setup) {
|
|
107
|
-
const repeater = new Repeater(async (push, stop) => {
|
|
108
|
-
const emit = (value) => {
|
|
109
|
-
Promise.resolve(push(value)).catch((error) => {
|
|
110
|
-
stop(error);
|
|
111
|
-
return void 0;
|
|
112
|
-
});
|
|
113
|
-
};
|
|
114
|
-
const end = (error) => {
|
|
115
|
-
stop(error);
|
|
116
|
-
};
|
|
117
|
-
const cleanup = await setup(emit, end);
|
|
118
|
-
try {
|
|
119
|
-
await stop;
|
|
120
|
-
} finally {
|
|
121
|
-
await cleanup?.();
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
return Object.assign(repeater, {
|
|
125
|
-
close: async () => {
|
|
126
|
-
await repeater.return(void 0);
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
function mergeStreams(streams) {
|
|
131
|
-
return stream((emit, end) => {
|
|
132
|
-
if (streams.length === 0) {
|
|
133
|
-
end();
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
let openStreams = streams.length;
|
|
137
|
-
const workers = streams.map(async (source) => {
|
|
138
|
-
try {
|
|
139
|
-
for await (const value of source) {
|
|
140
|
-
emit(value);
|
|
141
|
-
}
|
|
142
|
-
} catch (error) {
|
|
143
|
-
end(error);
|
|
144
|
-
} finally {
|
|
145
|
-
openStreams -= 1;
|
|
146
|
-
if (openStreams === 0) {
|
|
147
|
-
end();
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
return async () => {
|
|
152
|
-
await Promise.allSettled(streams.map((source) => source.close()));
|
|
153
|
-
await Promise.allSettled(workers);
|
|
154
|
-
};
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export {
|
|
159
|
-
asAttachment,
|
|
160
|
-
attachment,
|
|
161
|
-
asCustom,
|
|
162
|
-
custom,
|
|
163
|
-
stream,
|
|
164
|
-
mergeStreams
|
|
165
|
-
};
|
package/dist/chunk-XEEDIGVK.js
DELETED
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
// src/content/text.ts
|
|
2
|
-
import z from "zod";
|
|
3
|
-
var textSchema = z.object({
|
|
4
|
-
type: z.literal("text"),
|
|
5
|
-
text: z.string().nonempty()
|
|
6
|
-
});
|
|
7
|
-
var asText = (text2) => textSchema.parse({ type: "text", text: text2 });
|
|
8
|
-
function text(text2) {
|
|
9
|
-
return {
|
|
10
|
-
build: async () => asText(text2)
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// src/content/resolve.ts
|
|
15
|
-
var resolveContents = (items) => Promise.all(
|
|
16
|
-
items.map((c) => typeof c === "string" ? text(c).build() : c.build())
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
// src/platform/define.ts
|
|
20
|
-
function createPlatformInstance(def, runtime) {
|
|
21
|
-
const isPlatformUser = (value) => {
|
|
22
|
-
return typeof value === "object" && value !== null && "__platform" in value && value.__platform === def.name;
|
|
23
|
-
};
|
|
24
|
-
const normalizeSpaceArgs = (args) => {
|
|
25
|
-
if (args.length === 0) {
|
|
26
|
-
return { users: [], params: void 0 };
|
|
27
|
-
}
|
|
28
|
-
const [first, ...rest] = args;
|
|
29
|
-
if (Array.isArray(first)) {
|
|
30
|
-
return {
|
|
31
|
-
users: first,
|
|
32
|
-
params: rest[0]
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
if (!isPlatformUser(first)) {
|
|
36
|
-
return {
|
|
37
|
-
users: [],
|
|
38
|
-
params: first
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
const last = args.at(-1);
|
|
42
|
-
if (last !== void 0 && !isPlatformUser(last)) {
|
|
43
|
-
return {
|
|
44
|
-
users: args.slice(0, -1),
|
|
45
|
-
params: last
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
users: args,
|
|
50
|
-
params: void 0
|
|
51
|
-
};
|
|
52
|
-
};
|
|
53
|
-
const base = {
|
|
54
|
-
async user(userID) {
|
|
55
|
-
const resolved = await def.user.resolve({
|
|
56
|
-
input: { userID },
|
|
57
|
-
client: runtime.client,
|
|
58
|
-
config: runtime.config
|
|
59
|
-
});
|
|
60
|
-
return {
|
|
61
|
-
...resolved,
|
|
62
|
-
__platform: def.name
|
|
63
|
-
};
|
|
64
|
-
},
|
|
65
|
-
async space(...args) {
|
|
66
|
-
const { users, params } = normalizeSpaceArgs(args);
|
|
67
|
-
let parsedParams = params;
|
|
68
|
-
if (params !== void 0 && def.space.params) {
|
|
69
|
-
parsedParams = def.space.params.parse(params);
|
|
70
|
-
}
|
|
71
|
-
const resolved = await def.space.resolve({
|
|
72
|
-
input: { users, params: parsedParams },
|
|
73
|
-
client: runtime.client,
|
|
74
|
-
config: runtime.config
|
|
75
|
-
});
|
|
76
|
-
const parsedSpace = def.space.schema ? def.space.schema.parse(resolved) : resolved;
|
|
77
|
-
const spaceRef = {
|
|
78
|
-
id: parsedSpace.id,
|
|
79
|
-
__platform: def.name
|
|
80
|
-
};
|
|
81
|
-
const typingCtx = {
|
|
82
|
-
space: spaceRef,
|
|
83
|
-
client: runtime.client,
|
|
84
|
-
config: runtime.config
|
|
85
|
-
};
|
|
86
|
-
return {
|
|
87
|
-
...parsedSpace,
|
|
88
|
-
...spaceRef,
|
|
89
|
-
send: async (...content) => {
|
|
90
|
-
const built = await resolveContents(content);
|
|
91
|
-
for (const item of built) {
|
|
92
|
-
await def.actions.send({
|
|
93
|
-
...typingCtx,
|
|
94
|
-
content: item
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
startTyping: async () => {
|
|
99
|
-
await def.actions.startTyping?.(typingCtx);
|
|
100
|
-
},
|
|
101
|
-
stopTyping: async () => {
|
|
102
|
-
await def.actions.stopTyping?.(typingCtx);
|
|
103
|
-
},
|
|
104
|
-
responding: async (fn) => {
|
|
105
|
-
await def.actions.startTyping?.(typingCtx);
|
|
106
|
-
try {
|
|
107
|
-
return await fn();
|
|
108
|
-
} finally {
|
|
109
|
-
await def.actions.stopTyping?.(typingCtx).catch(() => {
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
const eventProperties = {};
|
|
117
|
-
for (const eventName of Object.keys(def.events)) {
|
|
118
|
-
if (eventName === "messages") {
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
const producer = def.events[eventName];
|
|
122
|
-
if (producer) {
|
|
123
|
-
eventProperties[eventName] = producer({
|
|
124
|
-
client: runtime.client,
|
|
125
|
-
config: runtime.config
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return Object.assign(base, eventProperties);
|
|
130
|
-
}
|
|
131
|
-
function definePlatform(name, def) {
|
|
132
|
-
const fullDef = { name, ...def };
|
|
133
|
-
const platformCache = /* @__PURE__ */ new WeakMap();
|
|
134
|
-
const narrowSpectrum = (spectrum) => {
|
|
135
|
-
const cached = platformCache.get(spectrum);
|
|
136
|
-
if (cached) {
|
|
137
|
-
return cached;
|
|
138
|
-
}
|
|
139
|
-
const runtime = spectrum.__internal.platforms.get(name);
|
|
140
|
-
if (!runtime) {
|
|
141
|
-
throw new Error(`Platform "${name}" is not registered`);
|
|
142
|
-
}
|
|
143
|
-
const instance = createPlatformInstance(
|
|
144
|
-
fullDef,
|
|
145
|
-
runtime
|
|
146
|
-
);
|
|
147
|
-
platformCache.set(spectrum, instance);
|
|
148
|
-
return instance;
|
|
149
|
-
};
|
|
150
|
-
const narrowSpace = (input) => {
|
|
151
|
-
if (input.__platform !== name) {
|
|
152
|
-
throw new Error(
|
|
153
|
-
`Expected space from "${name}", got "${input.__platform}"`
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
return input;
|
|
157
|
-
};
|
|
158
|
-
const narrowMessage = (input) => {
|
|
159
|
-
if (input.platform !== name) {
|
|
160
|
-
throw new Error(
|
|
161
|
-
`Expected message from "${name}", got "${input.platform}"`
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
return input;
|
|
165
|
-
};
|
|
166
|
-
const narrower = ((input) => {
|
|
167
|
-
if ("__providers" in input && "__internal" in input) {
|
|
168
|
-
return narrowSpectrum(input);
|
|
169
|
-
}
|
|
170
|
-
if ("__platform" in input && "send" in input) {
|
|
171
|
-
return narrowSpace(input);
|
|
172
|
-
}
|
|
173
|
-
if ("platform" in input && "sender" in input && "space" in input) {
|
|
174
|
-
return narrowMessage(input);
|
|
175
|
-
}
|
|
176
|
-
throw new Error("Invalid input to platform narrowing function");
|
|
177
|
-
});
|
|
178
|
-
narrower.config = (config) => {
|
|
179
|
-
const resolvedConfig = config ?? {};
|
|
180
|
-
return {
|
|
181
|
-
__tag: "PlatformProviderConfig",
|
|
182
|
-
__def: void 0,
|
|
183
|
-
__name: name,
|
|
184
|
-
config: resolvedConfig,
|
|
185
|
-
__definition: fullDef
|
|
186
|
-
};
|
|
187
|
-
};
|
|
188
|
-
if (def.static) {
|
|
189
|
-
Object.assign(narrower, def.static);
|
|
190
|
-
}
|
|
191
|
-
return narrower;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export {
|
|
195
|
-
asText,
|
|
196
|
-
text,
|
|
197
|
-
resolveContents,
|
|
198
|
-
definePlatform
|
|
199
|
-
};
|