spectrum-ts 0.2.1 → 0.3.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.
@@ -1,9 +1,14 @@
1
1
  import {
2
+ asAttachment
3
+ } from "../../chunk-ZRSCHSLZ.js";
4
+ import {
5
+ asCustom,
2
6
  stream
3
- } from "../../chunk-3TBRO2J7.js";
7
+ } from "../../chunk-V2PK557T.js";
4
8
  import {
9
+ asText,
5
10
  definePlatform
6
- } from "../../chunk-LIRM7SBA.js";
11
+ } from "../../chunk-XEEDIGVK.js";
7
12
 
8
13
  // src/providers/whatsapp-business/index.ts
9
14
  import {
@@ -24,67 +29,33 @@ var toMessage = async (client, msg) => {
24
29
  var mapContent = async (client, content) => {
25
30
  switch (content.type) {
26
31
  case "text":
27
- return [{ type: "plain_text", text: content.body }];
32
+ return asText(content.body);
28
33
  case "image":
29
34
  case "video":
30
35
  case "audio":
31
36
  case "document":
32
- return [await downloadMedia(client, content.media)];
37
+ return downloadMedia(client, content.media);
33
38
  case "sticker":
34
- return [
35
- {
36
- type: "custom",
37
- raw: { whatsapp_type: "sticker", ...content.sticker }
38
- }
39
- ];
39
+ return asCustom({ whatsapp_type: "sticker", ...content.sticker });
40
40
  case "location":
41
- return [
42
- {
43
- type: "custom",
44
- raw: { whatsapp_type: "location", ...content.location }
45
- }
46
- ];
41
+ return asCustom({ whatsapp_type: "location", ...content.location });
47
42
  case "contacts":
48
- return [
49
- {
50
- type: "custom",
51
- raw: { whatsapp_type: "contacts", contacts: content.contacts }
52
- }
53
- ];
43
+ return asCustom({
44
+ whatsapp_type: "contacts",
45
+ contacts: content.contacts
46
+ });
54
47
  case "reaction":
55
- return [
56
- {
57
- type: "custom",
58
- raw: { whatsapp_type: "reaction", ...content.reaction }
59
- }
60
- ];
48
+ return asCustom({ whatsapp_type: "reaction", ...content.reaction });
61
49
  case "interactive":
62
- return [
63
- {
64
- type: "custom",
65
- raw: { whatsapp_type: "interactive", ...content.interactive }
66
- }
67
- ];
50
+ return asCustom({ whatsapp_type: "interactive", ...content.interactive });
68
51
  case "button":
69
- return [
70
- {
71
- type: "custom",
72
- raw: { whatsapp_type: "button", ...content.button }
73
- }
74
- ];
52
+ return asCustom({ whatsapp_type: "button", ...content.button });
75
53
  case "order":
76
- return [
77
- { type: "custom", raw: { whatsapp_type: "order", ...content.order } }
78
- ];
54
+ return asCustom({ whatsapp_type: "order", ...content.order });
79
55
  case "system":
80
- return [
81
- {
82
- type: "custom",
83
- raw: { whatsapp_type: "system", ...content.system }
84
- }
85
- ];
56
+ return asCustom({ whatsapp_type: "system", ...content.system });
86
57
  default:
87
- return [{ type: "custom", raw: { whatsapp_type: "unknown" } }];
58
+ return asCustom({ whatsapp_type: "unknown" });
88
59
  }
89
60
  };
90
61
  var downloadMedia = async (client, media) => {
@@ -95,21 +66,17 @@ var downloadMedia = async (client, media) => {
95
66
  throw new Error(`Media download failed: ${response.status}`);
96
67
  }
97
68
  const data = Buffer.from(await response.arrayBuffer());
98
- return {
99
- type: "attachment",
69
+ return asAttachment({
100
70
  data,
101
71
  mimeType: media.mimeType,
102
72
  name: media.filename ?? `media-${media.id}`
103
- };
73
+ });
104
74
  } catch {
105
- return {
106
- type: "custom",
107
- raw: {
108
- whatsapp_type: "media_error",
109
- mediaId: media.id,
110
- mimeType: media.mimeType
111
- }
112
- };
75
+ return asCustom({
76
+ whatsapp_type: "media_error",
77
+ mediaId: media.id,
78
+ mimeType: media.mimeType
79
+ });
113
80
  }
114
81
  };
115
82
  var mimeToMediaType = (mimeType) => {
@@ -145,7 +112,7 @@ var messages = (client) => {
145
112
  };
146
113
  var send = async (client, spaceId, content) => {
147
114
  switch (content.type) {
148
- case "plain_text":
115
+ case "text":
149
116
  await client.messages.send({ to: spaceId, text: content.text });
150
117
  break;
151
118
  case "attachment": {
@@ -174,7 +141,7 @@ var reactToMessage = async (client, spaceId, messageId, reaction) => {
174
141
  };
175
142
  var replyToMessage = async (client, spaceId, messageId, content) => {
176
143
  switch (content.type) {
177
- case "plain_text":
144
+ case "text":
178
145
  await client.messages.send({
179
146
  to: spaceId,
180
147
  replyTo: messageId,
@@ -254,10 +221,7 @@ var whatsappBusiness = definePlatform("WhatsApp Business", {
254
221
  },
255
222
  actions: {
256
223
  send: async ({ space, content, client }) => {
257
- const wa = client;
258
- for (const item of content) {
259
- await send(wa, space.id, item);
260
- }
224
+ await send(client, space.id, content);
261
225
  },
262
226
  reactToMessage: async ({ space, messageId, reaction, client }) => {
263
227
  await reactToMessage(
@@ -268,10 +232,12 @@ var whatsappBusiness = definePlatform("WhatsApp Business", {
268
232
  );
269
233
  },
270
234
  replyToMessage: async ({ space, messageId, content, client }) => {
271
- const wa = client;
272
- for (const item of content) {
273
- await replyToMessage(wa, space.id, messageId, item);
274
- }
235
+ await replyToMessage(
236
+ client,
237
+ space.id,
238
+ messageId,
239
+ content
240
+ );
275
241
  }
276
242
  }
277
243
  });
@@ -1,13 +1,12 @@
1
1
  import { Pipe, Tuples, Fn } from 'hotscript';
2
2
  import z__default from 'zod';
3
- import { NonEmptyString } from 'type-fest';
4
3
 
5
4
  declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObject<{
6
- type: z__default.ZodLiteral<"plain_text">;
5
+ type: z__default.ZodLiteral<"text">;
7
6
  text: z__default.ZodString;
8
7
  }, z__default.core.$strip>, z__default.ZodObject<{
9
8
  type: z__default.ZodLiteral<"custom">;
10
- raw: z__default.ZodJSONSchema;
9
+ raw: z__default.ZodUnknown;
11
10
  }, z__default.core.$strip>, z__default.ZodObject<{
12
11
  type: z__default.ZodLiteral<"attachment">;
13
12
  data: z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>;
@@ -18,18 +17,13 @@ type Content = z__default.infer<typeof contentSchema>;
18
17
  interface ContentBuilder {
19
18
  build(): Promise<Content>;
20
19
  }
21
- declare function text<T extends string>(text: NonEmptyString<T>): ContentBuilder;
22
- declare function custom(raw: z__default.infer<ReturnType<typeof z__default.json>>): ContentBuilder;
23
- declare function attachment(input: string | Buffer, options?: {
24
- mimeType?: string;
25
- name?: string;
26
- }): ContentBuilder;
20
+ type ContentInput = string | ContentBuilder;
27
21
 
28
22
  interface Space<_Def = unknown> {
29
23
  readonly __platform: string;
30
24
  readonly id: string;
31
25
  responding<T>(fn: () => T | Promise<T>): Promise<T>;
32
- send(...content: [ContentBuilder, ...ContentBuilder[]]): Promise<void>;
26
+ send(...content: [ContentInput, ...ContentInput[]]): Promise<void>;
33
27
  startTyping(): Promise<void>;
34
28
  stopTyping(): Promise<void>;
35
29
  }
@@ -40,11 +34,11 @@ interface User {
40
34
  }
41
35
 
42
36
  interface Message<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> {
43
- content: Content[];
37
+ content: Content;
44
38
  readonly id: string;
45
39
  platform: TPlatform;
46
40
  react(reaction: string): Promise<void>;
47
- reply(...content: [ContentBuilder, ...ContentBuilder[]]): Promise<void>;
41
+ reply(...content: [ContentInput, ...ContentInput[]]): Promise<void>;
48
42
  sender: TSender;
49
43
  space: TSpace;
50
44
  timestamp: Date;
@@ -66,7 +60,7 @@ type EventProducer<TPayload = unknown, TClient = unknown, TConfig = unknown> = (
66
60
  }) => AsyncIterable<TPayload>;
67
61
  type ProviderMessage<TSender extends ResolvedUser = ResolvedUser, TSpace extends ResolvedSpace = ResolvedSpace, TExtra extends object = Record<never, never>> = {
68
62
  id: string;
69
- content: Content[];
63
+ content: Content;
70
64
  sender: TSender;
71
65
  space: TSpace;
72
66
  timestamp?: Date;
@@ -83,7 +77,7 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
83
77
  actions: {
84
78
  send: (_: {
85
79
  space: _ResolvedSpace & SpaceRef;
86
- content: Content[];
80
+ content: Content;
87
81
  client: _Client;
88
82
  config: z__default.infer<_ConfigSchema>;
89
83
  }) => Promise<void>;
@@ -107,7 +101,7 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
107
101
  replyToMessage?: (_: {
108
102
  space: _ResolvedSpace & SpaceRef;
109
103
  messageId: string;
110
- content: Content[];
104
+ content: Content;
111
105
  client: _Client;
112
106
  config: z__default.infer<_ConfigSchema>;
113
107
  }) => Promise<void>;
@@ -258,4 +252,4 @@ interface Platform<Def extends AnyPlatformDef> {
258
252
  (message: Message): PlatformMessage<Def>;
259
253
  }
260
254
 
261
- export { type AnyPlatformDef as A, type CustomEventStreams as C, type EventProducer as E, type Message as M, type ProviderMessage as P, type SpectrumLike as S, type User as U, type PlatformDef as a, type Platform as b, type PlatformProviderConfig as c, type Space as d, type ContentBuilder as e, type Content as f, type PlatformInstance as g, type PlatformMessage as h, type PlatformSpace as i, type PlatformUser as j, type SchemaMessage as k, attachment as l, custom as m, text as t };
255
+ export type { AnyPlatformDef as A, ContentBuilder as C, EventProducer as E, Message as M, ProviderMessage as P, SpectrumLike as S, User as U, ContentInput as a, Content as b, PlatformDef as c, Platform as d, PlatformProviderConfig as e, CustomEventStreams as f, Space as g, PlatformInstance as h, PlatformMessage as i, PlatformSpace as j, PlatformUser as k, SchemaMessage as l };
package/package.json CHANGED
@@ -1,56 +1,33 @@
1
1
  {
2
2
  "name": "spectrum-ts",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
8
  "files": [
9
- "dist",
10
- "src"
9
+ "dist"
11
10
  ],
12
11
  "exports": {
13
12
  ".": {
14
13
  "types": "./dist/index.d.ts",
15
- "bun": "./src/index.ts",
16
14
  "default": "./dist/index.js"
17
15
  },
18
- "./providers/imessage": {
19
- "types": "./dist/providers/imessage/index.d.ts",
20
- "bun": "./src/providers/imessage/index.ts",
21
- "default": "./dist/providers/imessage/index.js"
22
- },
23
- "./providers/terminal": {
24
- "types": "./dist/providers/terminal/index.d.ts",
25
- "bun": "./src/providers/terminal/index.ts",
26
- "default": "./dist/providers/terminal/index.js"
27
- },
28
- "./providers/whatsapp-business": {
29
- "types": "./dist/providers/whatsapp-business/index.d.ts",
30
- "bun": "./src/providers/whatsapp-business/index.ts",
31
- "default": "./dist/providers/whatsapp-business/index.js"
16
+ "./providers/*": {
17
+ "types": "./dist/providers/*/index.d.ts",
18
+ "default": "./dist/providers/*/index.js"
32
19
  }
33
20
  },
34
- "scripts": {
35
- "build": "tsup",
36
- "dev": "tsup --watch"
37
- },
38
21
  "dependencies": {
39
22
  "@photon-ai/advanced-imessage": "^0.4.2",
40
23
  "@photon-ai/whatsapp-business": "^0.1.1",
41
- "@photon-ai/imessage-kit": "^2.1.2",
24
+ "@photon-ai/imessage-kit": "^3.0.0-rc.1",
42
25
  "@repeaterjs/repeater": "^3.0.6",
43
26
  "better-grpc": "^0.3.2",
44
27
  "mime-types": "^3.0.1",
45
28
  "type-fest": "^5.4.1",
46
29
  "zod": "^4.2.1"
47
30
  },
48
- "devDependencies": {
49
- "@types/bun": "latest",
50
- "@types/mime-types": "^3.0.1",
51
- "hotscript": "^1.0.13",
52
- "tsup": "^8.4.0"
53
- },
54
31
  "peerDependencies": {
55
32
  "typescript": "^5"
56
33
  },
package/src/index.ts DELETED
@@ -1,38 +0,0 @@
1
- // biome-ignore lint/performance/noBarrelFile: library entry point
2
- export { definePlatform } from "./platform/define";
3
- export type {
4
- AnyPlatformDef,
5
- EventProducer,
6
- Platform,
7
- PlatformDef,
8
- PlatformInstance,
9
- PlatformMessage,
10
- PlatformProviderConfig,
11
- PlatformSpace,
12
- PlatformUser,
13
- SchemaMessage,
14
- } from "./platform/types";
15
- export { Spectrum, type SpectrumInstance } from "./spectrum";
16
- export {
17
- attachment,
18
- type Content,
19
- type ContentBuilder,
20
- custom,
21
- text,
22
- } from "./types/content";
23
- export type { Message } from "./types/message";
24
- export type { Space } from "./types/space";
25
- export type { User } from "./types/user";
26
- export type {
27
- CloudPlatform,
28
- DedicatedTokenData,
29
- ImessageInfoData,
30
- PlatformStatus,
31
- PlatformsData,
32
- SharedTokenData,
33
- SubscriptionData,
34
- SubscriptionStatus,
35
- TokenData,
36
- } from "./utils/cloud";
37
- export { cloud, SpectrumCloudError } from "./utils/cloud";
38
- export { type ManagedStream, mergeStreams, stream } from "./utils/stream";
@@ -1,308 +0,0 @@
1
- import type z from "zod";
2
- import type { ContentBuilder } from "../types/content";
3
- import type { Message } from "../types/message";
4
- import type { Space } from "../types/space";
5
- import type {
6
- AnyPlatformDef,
7
- Platform,
8
- PlatformDef,
9
- PlatformInstance,
10
- PlatformMessage,
11
- PlatformProviderConfig,
12
- PlatformSpace,
13
- PlatformUser,
14
- ProviderMessage,
15
- SpectrumLike,
16
- } from "./types";
17
-
18
- function createPlatformInstance<
19
- Def extends AnyPlatformDef,
20
- _Client,
21
- _ConfigSchema extends z.ZodType<object>,
22
- >(
23
- def: Def,
24
- runtime: { client: unknown; config: unknown }
25
- ): PlatformInstance<Def> {
26
- const isPlatformUser = (value: unknown): value is PlatformUser<Def> => {
27
- return (
28
- typeof value === "object" &&
29
- value !== null &&
30
- "__platform" in value &&
31
- (value as { __platform?: unknown }).__platform === def.name
32
- );
33
- };
34
-
35
- const normalizeSpaceArgs = (
36
- args: unknown[]
37
- ): { users: PlatformUser<Def>[]; params: unknown } => {
38
- if (args.length === 0) {
39
- return { users: [], params: undefined };
40
- }
41
-
42
- const [first, ...rest] = args;
43
- if (Array.isArray(first)) {
44
- return {
45
- users: first as PlatformUser<Def>[],
46
- params: rest[0],
47
- };
48
- }
49
-
50
- if (!isPlatformUser(first)) {
51
- return {
52
- users: [],
53
- params: first,
54
- };
55
- }
56
-
57
- const last = args.at(-1);
58
- if (last !== undefined && !isPlatformUser(last)) {
59
- return {
60
- users: args.slice(0, -1) as PlatformUser<Def>[],
61
- params: last,
62
- };
63
- }
64
-
65
- return {
66
- users: args as PlatformUser<Def>[],
67
- params: undefined,
68
- };
69
- };
70
-
71
- const base = {
72
- async user(userID: string) {
73
- const resolved = await def.user.resolve({
74
- input: { userID },
75
- client: runtime.client as _Client,
76
- config: runtime.config as z.infer<_ConfigSchema>,
77
- });
78
- return {
79
- ...resolved,
80
- __platform: def.name,
81
- } as PlatformUser<Def>;
82
- },
83
-
84
- async space(...args: unknown[]) {
85
- const { users, params } = normalizeSpaceArgs(args);
86
- let parsedParams = params;
87
- if (params !== undefined && def.space.params) {
88
- parsedParams = def.space.params.parse(params);
89
- }
90
- const resolved = await def.space.resolve({
91
- input: { users, params: parsedParams },
92
- client: runtime.client as _Client,
93
- config: runtime.config as z.infer<_ConfigSchema>,
94
- });
95
- const parsedSpace = def.space.schema
96
- ? def.space.schema.parse(resolved)
97
- : resolved;
98
- const spaceRef = {
99
- id: parsedSpace.id,
100
- __platform: def.name,
101
- };
102
- const typingCtx = {
103
- space: spaceRef,
104
- client: runtime.client as _Client,
105
- config: runtime.config as z.infer<_ConfigSchema>,
106
- };
107
- return {
108
- ...parsedSpace,
109
- ...spaceRef,
110
- send: async (...content: [ContentBuilder, ...ContentBuilder[]]) => {
111
- const built = await Promise.all(content.map((c) => c.build()));
112
- await def.actions.send({
113
- ...typingCtx,
114
- content: built,
115
- });
116
- },
117
- startTyping: async () => {
118
- await def.actions.startTyping?.(typingCtx);
119
- },
120
- stopTyping: async () => {
121
- await def.actions.stopTyping?.(typingCtx);
122
- },
123
- responding: async <T>(fn: () => T | Promise<T>): Promise<T> => {
124
- await def.actions.startTyping?.(typingCtx);
125
- try {
126
- return await fn();
127
- } finally {
128
- await def.actions.stopTyping?.(typingCtx).catch(() => {});
129
- }
130
- },
131
- } as PlatformSpace<Def>;
132
- },
133
- };
134
-
135
- // Add flat event properties for custom events (non-messages)
136
- const eventProperties: Record<string, AsyncIterable<unknown>> = {};
137
- for (const eventName of Object.keys(def.events)) {
138
- if (eventName === "messages") {
139
- continue;
140
- }
141
- const producer = def.events[eventName] as
142
- | ((ctx: { client: unknown; config: unknown }) => AsyncIterable<unknown>)
143
- | undefined;
144
- if (producer) {
145
- eventProperties[eventName] = producer({
146
- client: runtime.client,
147
- config: runtime.config,
148
- });
149
- }
150
- }
151
-
152
- return Object.assign(base, eventProperties) as PlatformInstance<Def>;
153
- }
154
-
155
- export function definePlatform<
156
- _Name extends string,
157
- _ConfigSchema extends z.ZodType<object>,
158
- _UserSchema extends z.ZodType<object> | undefined,
159
- _SpaceSchema extends z.ZodType<object> | undefined,
160
- _SpaceParamsSchema extends z.ZodType<object> | undefined,
161
- _Client,
162
- _ResolvedUser extends { id: string },
163
- _ResolvedSpace extends { id: string },
164
- _MessageSchema extends z.ZodType<object> | undefined = undefined,
165
- _MessageType extends ProviderMessage<
166
- _ResolvedUser,
167
- _ResolvedSpace,
168
- _MessageSchema extends z.ZodType<object>
169
- ? z.infer<_MessageSchema>
170
- : Record<never, never>
171
- > = ProviderMessage<
172
- _ResolvedUser,
173
- _ResolvedSpace,
174
- _MessageSchema extends z.ZodType<object>
175
- ? z.infer<_MessageSchema>
176
- : Record<never, never>
177
- >,
178
- _Events extends {
179
- messages: (ctx: {
180
- client: _Client;
181
- config: z.infer<_ConfigSchema>;
182
- }) => AsyncIterable<_MessageType>;
183
- } = {
184
- messages: (ctx: {
185
- client: _Client;
186
- config: z.infer<_ConfigSchema>;
187
- }) => AsyncIterable<_MessageType>;
188
- },
189
- _Static extends Record<string, unknown> = Record<never, never>,
190
- >(
191
- name: _Name,
192
- def: Omit<
193
- PlatformDef<
194
- _Name,
195
- _ConfigSchema,
196
- _UserSchema,
197
- _SpaceSchema,
198
- _SpaceParamsSchema,
199
- _Client,
200
- _ResolvedUser,
201
- _ResolvedSpace,
202
- _MessageSchema,
203
- _MessageType,
204
- _Events
205
- >,
206
- "name"
207
- > & { static?: _Static }
208
- ): Platform<
209
- PlatformDef<
210
- _Name,
211
- _ConfigSchema,
212
- _UserSchema,
213
- _SpaceSchema,
214
- _SpaceParamsSchema,
215
- _Client,
216
- _ResolvedUser,
217
- _ResolvedSpace,
218
- _MessageSchema,
219
- _MessageType,
220
- _Events
221
- >
222
- > &
223
- Readonly<_Static> {
224
- type Def = PlatformDef<
225
- _Name,
226
- _ConfigSchema,
227
- _UserSchema,
228
- _SpaceSchema,
229
- _SpaceParamsSchema,
230
- _Client,
231
- _ResolvedUser,
232
- _ResolvedSpace,
233
- _MessageSchema,
234
- _MessageType,
235
- _Events
236
- >;
237
-
238
- const fullDef = { name, ...def };
239
-
240
- const platformCache = new WeakMap<SpectrumLike, PlatformInstance<Def>>();
241
-
242
- const narrowSpectrum = (spectrum: SpectrumLike) => {
243
- const cached = platformCache.get(spectrum);
244
- if (cached) {
245
- return cached;
246
- }
247
-
248
- const runtime = spectrum.__internal.platforms.get(name);
249
- if (!runtime) {
250
- throw new Error(`Platform "${name}" is not registered`);
251
- }
252
-
253
- const instance = createPlatformInstance<Def, _Client, _ConfigSchema>(
254
- fullDef as Def & AnyPlatformDef,
255
- runtime
256
- );
257
- platformCache.set(spectrum, instance);
258
- return instance;
259
- };
260
-
261
- const narrowSpace = (input: Space) => {
262
- if (input.__platform !== name) {
263
- throw new Error(
264
- `Expected space from "${name}", got "${input.__platform}"`
265
- );
266
- }
267
- return input as PlatformSpace<Def>;
268
- };
269
-
270
- const narrowMessage = (input: Message) => {
271
- if (input.platform !== name) {
272
- throw new Error(
273
- `Expected message from "${name}", got "${input.platform}"`
274
- );
275
- }
276
- return input as PlatformMessage<Def>;
277
- };
278
-
279
- const narrower = ((input: SpectrumLike | Space | Message) => {
280
- if ("__providers" in input && "__internal" in input) {
281
- return narrowSpectrum(input as SpectrumLike);
282
- }
283
- if ("__platform" in input && "send" in input) {
284
- return narrowSpace(input as Space);
285
- }
286
- if ("platform" in input && "sender" in input && "space" in input) {
287
- return narrowMessage(input as Message);
288
- }
289
- throw new Error("Invalid input to platform narrowing function");
290
- }) as Platform<Def>;
291
-
292
- narrower.config = (config?: z.input<_ConfigSchema>) => {
293
- const resolvedConfig = config ?? {};
294
- return {
295
- __tag: "PlatformProviderConfig" as const,
296
- __def: undefined as unknown as Def,
297
- __name: name,
298
- config: resolvedConfig,
299
- __definition: fullDef as AnyPlatformDef,
300
- } satisfies PlatformProviderConfig<Def> as PlatformProviderConfig<Def>;
301
- };
302
-
303
- if (def.static) {
304
- Object.assign(narrower, def.static);
305
- }
306
-
307
- return narrower as Platform<Def> & Readonly<_Static>;
308
- }