@marcoappio/marco-config 2.0.594 → 2.0.595
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/appwrite/appwrite.d.ts +47 -2
- package/dist/appwrite/appwrite.d.ts.map +1 -1
- package/dist/appwrite/appwrite.js +28 -1
- package/dist/appwrite/appwrite.test.js +54 -0
- package/dist/appwrite/functions.d.ts +5 -3
- package/dist/appwrite/functions.d.ts.map +1 -1
- package/dist/appwrite/functions.js +4 -2
- package/dist/appwrite/functions.test.js +60 -2
- package/dist/marcoPublicConfig.d.ts +4 -0
- package/dist/marcoPublicConfig.d.ts.map +1 -1
- package/dist/marcoPublicConfig.js +12 -0
- package/package.json +1 -1
|
@@ -108,8 +108,9 @@ declare const rowSchemas: {
|
|
|
108
108
|
readonly $updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
109
109
|
}, undefined>;
|
|
110
110
|
readonly credentials: v.StrictObjectSchema<{
|
|
111
|
+
readonly accountId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
111
112
|
readonly encryptedPayload: v.StringSchema<undefined>;
|
|
112
|
-
readonly expiresAt: v.
|
|
113
|
+
readonly expiresAt: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
|
|
113
114
|
readonly provider: v.PicklistSchema<readonly ["GMAIL", "OUTLOOK", "IMAP"], undefined>;
|
|
114
115
|
readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
115
116
|
readonly $createdAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
@@ -226,6 +227,24 @@ declare const rowSchemas: {
|
|
|
226
227
|
readonly $tableId: v.LiteralSchema<"messages", undefined>;
|
|
227
228
|
readonly $updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
228
229
|
}, undefined>;
|
|
230
|
+
readonly oauthStates: v.StrictObjectSchema<{
|
|
231
|
+
readonly accountId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
232
|
+
readonly email: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>;
|
|
233
|
+
readonly expiresAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
234
|
+
readonly nonceHash: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
235
|
+
readonly operation: v.PicklistSchema<readonly ["CONNECT", "REPLACE"], undefined>;
|
|
236
|
+
readonly profile: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
237
|
+
readonly provider: v.PicklistSchema<readonly ["GMAIL", "OUTLOOK"], undefined>;
|
|
238
|
+
readonly returnUri: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/provider-selection", "https://app.staging.marcoapp.io/onboarding/provider-selection"], undefined>;
|
|
239
|
+
readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
240
|
+
readonly $createdAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
241
|
+
readonly $databaseId: v.LiteralSchema<"marco", undefined>;
|
|
242
|
+
readonly $id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 36, undefined>, v.RegexAction<string, undefined>]>;
|
|
243
|
+
readonly $permissions: v.ArraySchema<v.StringSchema<undefined>, undefined>;
|
|
244
|
+
readonly $sequence: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
245
|
+
readonly $tableId: v.LiteralSchema<"oauth_states", undefined>;
|
|
246
|
+
readonly $updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
247
|
+
}, undefined>;
|
|
229
248
|
readonly profiles: v.StrictObjectSchema<{
|
|
230
249
|
readonly avatarFileId: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 36, undefined>, v.RegexAction<string, undefined>]>, undefined>;
|
|
231
250
|
readonly deletionRequestedAt: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
|
|
@@ -376,6 +395,7 @@ export declare const appwrite: {
|
|
|
376
395
|
readonly labels: "labels";
|
|
377
396
|
readonly mailboxSyncStates: "mailbox_sync_states";
|
|
378
397
|
readonly messages: "messages";
|
|
398
|
+
readonly oauthStates: "oauth_states";
|
|
379
399
|
readonly profiles: "profiles";
|
|
380
400
|
readonly pushNotificationTokens: "push_notification_tokens";
|
|
381
401
|
readonly savedViews: "saved_views";
|
|
@@ -384,6 +404,12 @@ export declare const appwrite: {
|
|
|
384
404
|
readonly watcherShards: "watcher_shards";
|
|
385
405
|
};
|
|
386
406
|
};
|
|
407
|
+
readonly oauth: {
|
|
408
|
+
readonly operations: readonly ["CONNECT", "REPLACE"];
|
|
409
|
+
readonly providers: readonly ["GMAIL", "OUTLOOK"];
|
|
410
|
+
readonly returnUriSchema: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/provider-selection", "https://app.staging.marcoapp.io/onboarding/provider-selection"], undefined>;
|
|
411
|
+
readonly returnUris: readonly ["https://app.marcoapp.io/onboarding/provider-selection", "https://app.staging.marcoapp.io/onboarding/provider-selection"];
|
|
412
|
+
};
|
|
387
413
|
readonly rowSchemas: {
|
|
388
414
|
readonly accounts: v.StrictObjectSchema<{
|
|
389
415
|
readonly colour: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 64, undefined>]>;
|
|
@@ -463,8 +489,9 @@ export declare const appwrite: {
|
|
|
463
489
|
readonly $updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
464
490
|
}, undefined>;
|
|
465
491
|
readonly credentials: v.StrictObjectSchema<{
|
|
492
|
+
readonly accountId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
466
493
|
readonly encryptedPayload: v.StringSchema<undefined>;
|
|
467
|
-
readonly expiresAt: v.
|
|
494
|
+
readonly expiresAt: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
|
|
468
495
|
readonly provider: v.PicklistSchema<readonly ["GMAIL", "OUTLOOK", "IMAP"], undefined>;
|
|
469
496
|
readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
470
497
|
readonly $createdAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
@@ -581,6 +608,24 @@ export declare const appwrite: {
|
|
|
581
608
|
readonly $tableId: v.LiteralSchema<"messages", undefined>;
|
|
582
609
|
readonly $updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
583
610
|
}, undefined>;
|
|
611
|
+
readonly oauthStates: v.StrictObjectSchema<{
|
|
612
|
+
readonly accountId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
613
|
+
readonly email: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>;
|
|
614
|
+
readonly expiresAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
615
|
+
readonly nonceHash: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
616
|
+
readonly operation: v.PicklistSchema<readonly ["CONNECT", "REPLACE"], undefined>;
|
|
617
|
+
readonly profile: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
618
|
+
readonly provider: v.PicklistSchema<readonly ["GMAIL", "OUTLOOK"], undefined>;
|
|
619
|
+
readonly returnUri: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/provider-selection", "https://app.staging.marcoapp.io/onboarding/provider-selection"], undefined>;
|
|
620
|
+
readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
621
|
+
readonly $createdAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
622
|
+
readonly $databaseId: v.LiteralSchema<"marco", undefined>;
|
|
623
|
+
readonly $id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 36, undefined>, v.RegexAction<string, undefined>]>;
|
|
624
|
+
readonly $permissions: v.ArraySchema<v.StringSchema<undefined>, undefined>;
|
|
625
|
+
readonly $sequence: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
626
|
+
readonly $tableId: v.LiteralSchema<"oauth_states", undefined>;
|
|
627
|
+
readonly $updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
628
|
+
}, undefined>;
|
|
584
629
|
readonly profiles: v.StrictObjectSchema<{
|
|
585
630
|
readonly avatarFileId: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 36, undefined>, v.RegexAction<string, undefined>]>, undefined>;
|
|
586
631
|
readonly deletionRequestedAt: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appwrite.d.ts","sourceRoot":"","sources":["../../src/appwrite/appwrite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAgB5B,QAAA,MAAM,qBAAqB;;;;;aAKzB,CAAA;AAEF,QAAA,MAAM,mBAAmB;;;;;eASxB,CAAA;AACD,QAAA,MAAM,uBAAuB;;;;;;;aAO3B,CAAA;AAEF,QAAA,MAAM,sBAAsB;;;;aAI1B,CAAA;AAGF,MAAM,MAAM,uBAAuB,GAAG,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,qBAAqB,CAAC,CAAC,CAAA;AAC/F,MAAM,MAAM,qBAAqB,GAAG,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAA;AAC3F,MAAM,MAAM,yBAAyB,GAAG,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,uBAAuB,CAAC,CAAC,CAAA;AACnG,MAAM,MAAM,wBAAwB,GAAG,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"appwrite.d.ts","sourceRoot":"","sources":["../../src/appwrite/appwrite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAgB5B,QAAA,MAAM,qBAAqB;;;;;aAKzB,CAAA;AAEF,QAAA,MAAM,mBAAmB;;;;;eASxB,CAAA;AACD,QAAA,MAAM,uBAAuB;;;;;;;aAO3B,CAAA;AAEF,QAAA,MAAM,sBAAsB;;;;aAI1B,CAAA;AAGF,MAAM,MAAM,uBAAuB,GAAG,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,qBAAqB,CAAC,CAAC,CAAA;AAC/F,MAAM,MAAM,qBAAqB,GAAG,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAA;AAC3F,MAAM,MAAM,yBAAyB,GAAG,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,uBAAuB,CAAC,CAAC,CAAA;AACnG,MAAM,MAAM,wBAAwB,GAAG,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAA;AA2DjG,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuNN,CAAA;AAEV,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiBX,CAAA;AAEV,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,UAAU,CAAA;AACtD,MAAM,MAAM,WAAW,CAAC,MAAM,SAAS,gBAAgB,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA"}
|
|
@@ -43,6 +43,13 @@ const draftTypes = ['COMPOSE', 'REPLY', 'FORWARD'];
|
|
|
43
43
|
const jobStates = ['PENDING', 'RUNNING', 'SUCCEEDED', 'FAILED', 'CANCELLED'];
|
|
44
44
|
const labelSpecialUses = ['ALL', 'ARCHIVE', 'DRAFTS', 'INBOX', 'JUNK', 'SENT', 'STARRED', 'TRASH'];
|
|
45
45
|
const mailboxSyncStates = ['INITIAL', 'SYNCING', 'IDLE', 'ERROR'];
|
|
46
|
+
const oauthOperations = ['CONNECT', 'REPLACE'];
|
|
47
|
+
const oauthProviders = ['GMAIL', 'OUTLOOK'];
|
|
48
|
+
const oauthReturnUris = [
|
|
49
|
+
'https://app.marcoapp.io/onboarding/provider-selection',
|
|
50
|
+
'https://app.staging.marcoapp.io/onboarding/provider-selection',
|
|
51
|
+
];
|
|
52
|
+
const oauthReturnUriSchema = v.picklist(oauthReturnUris);
|
|
46
53
|
const watcherShardStates = ['ACTIVE', 'IDLE', 'STOPPED', 'FAILED'];
|
|
47
54
|
const appwriteIds = {
|
|
48
55
|
bucket: 'marco-files',
|
|
@@ -62,6 +69,7 @@ const appwriteIds = {
|
|
|
62
69
|
labels: 'labels',
|
|
63
70
|
mailboxSyncStates: 'mailbox_sync_states',
|
|
64
71
|
messages: 'messages',
|
|
72
|
+
oauthStates: 'oauth_states',
|
|
65
73
|
profiles: 'profiles',
|
|
66
74
|
pushNotificationTokens: 'push_notification_tokens',
|
|
67
75
|
savedViews: 'saved_views',
|
|
@@ -135,8 +143,9 @@ const rowSchemas = {
|
|
|
135
143
|
}),
|
|
136
144
|
credentials: v.strictObject({
|
|
137
145
|
...wireMetadata(appwriteIds.tables.credentials),
|
|
146
|
+
accountId: identifierSchema,
|
|
138
147
|
encryptedPayload: v.string(),
|
|
139
|
-
expiresAt: v.
|
|
148
|
+
expiresAt: v.nullable(timestampSchema),
|
|
140
149
|
provider: v.picklist(accountProviders),
|
|
141
150
|
userId: identifierSchema,
|
|
142
151
|
}),
|
|
@@ -216,6 +225,18 @@ const rowSchemas = {
|
|
|
216
225
|
threadId: identifierSchema,
|
|
217
226
|
userId: identifierSchema,
|
|
218
227
|
}),
|
|
228
|
+
oauthStates: v.strictObject({
|
|
229
|
+
...wireMetadata(appwriteIds.tables.oauthStates),
|
|
230
|
+
accountId: identifierSchema,
|
|
231
|
+
email: emailSchema,
|
|
232
|
+
expiresAt: timestampSchema,
|
|
233
|
+
nonceHash: identifierSchema,
|
|
234
|
+
operation: v.picklist(oauthOperations),
|
|
235
|
+
profile: identifierSchema,
|
|
236
|
+
provider: v.picklist(oauthProviders),
|
|
237
|
+
returnUri: oauthReturnUriSchema,
|
|
238
|
+
userId: identifierSchema,
|
|
239
|
+
}),
|
|
219
240
|
profiles: v.strictObject({
|
|
220
241
|
...wireMetadata(appwriteIds.tables.profiles),
|
|
221
242
|
avatarFileId: v.nullable(appwriteRowIdSchema),
|
|
@@ -292,5 +313,11 @@ export const appwrite = {
|
|
|
292
313
|
messageRecipients: messageRecipientsSchema,
|
|
293
314
|
},
|
|
294
315
|
ids: appwriteIds,
|
|
316
|
+
oauth: {
|
|
317
|
+
operations: oauthOperations,
|
|
318
|
+
providers: oauthProviders,
|
|
319
|
+
returnUriSchema: oauthReturnUriSchema,
|
|
320
|
+
returnUris: oauthReturnUris,
|
|
321
|
+
},
|
|
295
322
|
rowSchemas,
|
|
296
323
|
};
|
|
@@ -66,7 +66,9 @@ const validRows = {
|
|
|
66
66
|
credentials: {
|
|
67
67
|
...metadata,
|
|
68
68
|
$tableId: 'credentials',
|
|
69
|
+
accountId: 'account-1',
|
|
69
70
|
encryptedPayload: 'encrypted-payload',
|
|
71
|
+
expiresAt: null,
|
|
70
72
|
provider: 'GMAIL',
|
|
71
73
|
userId: 'user-1',
|
|
72
74
|
},
|
|
@@ -151,6 +153,19 @@ const validRows = {
|
|
|
151
153
|
threadId: 'thread-1',
|
|
152
154
|
userId: 'user-1',
|
|
153
155
|
},
|
|
156
|
+
oauthStates: {
|
|
157
|
+
...metadata,
|
|
158
|
+
$tableId: 'oauth_states',
|
|
159
|
+
accountId: 'account-1',
|
|
160
|
+
email: 'marco@example.com',
|
|
161
|
+
expiresAt: '2026-07-15T00:10:00.000Z',
|
|
162
|
+
nonceHash: 'test-nonce-hash-1',
|
|
163
|
+
operation: 'CONNECT',
|
|
164
|
+
profile: 'user-1',
|
|
165
|
+
provider: 'GMAIL',
|
|
166
|
+
returnUri: 'https://app.marcoapp.io/onboarding/provider-selection',
|
|
167
|
+
userId: 'user-1',
|
|
168
|
+
},
|
|
154
169
|
profiles: {
|
|
155
170
|
...metadata,
|
|
156
171
|
$tableId: 'profiles',
|
|
@@ -239,6 +254,7 @@ describe('appwrite', () => {
|
|
|
239
254
|
labels: 'labels',
|
|
240
255
|
mailboxSyncStates: 'mailbox_sync_states',
|
|
241
256
|
messages: 'messages',
|
|
257
|
+
oauthStates: 'oauth_states',
|
|
242
258
|
profiles: 'profiles',
|
|
243
259
|
pushNotificationTokens: 'push_notification_tokens',
|
|
244
260
|
savedViews: 'saved_views',
|
|
@@ -248,6 +264,16 @@ describe('appwrite', () => {
|
|
|
248
264
|
},
|
|
249
265
|
});
|
|
250
266
|
});
|
|
267
|
+
it('exports the shared OAuth state contract', () => {
|
|
268
|
+
expect(appwrite.oauth).toMatchObject({
|
|
269
|
+
operations: ['CONNECT', 'REPLACE'],
|
|
270
|
+
providers: ['GMAIL', 'OUTLOOK'],
|
|
271
|
+
returnUris: [
|
|
272
|
+
'https://app.marcoapp.io/onboarding/provider-selection',
|
|
273
|
+
'https://app.staging.marcoapp.io/onboarding/provider-selection',
|
|
274
|
+
],
|
|
275
|
+
});
|
|
276
|
+
});
|
|
251
277
|
const rowTestCases = Object.keys(validRows);
|
|
252
278
|
for (const table of rowTestCases) {
|
|
253
279
|
it(`accepts the ${table} wire row`, () => {
|
|
@@ -258,6 +284,34 @@ describe('appwrite', () => {
|
|
|
258
284
|
expect(v.safeParse(appwrite.rowSchemas[table], rowWithoutId).success).toBe(false);
|
|
259
285
|
});
|
|
260
286
|
}
|
|
287
|
+
const validOAuthStates = [
|
|
288
|
+
{ expected: true, operation: 'CONNECT', provider: 'GMAIL' },
|
|
289
|
+
{ expected: true, operation: 'REPLACE', provider: 'OUTLOOK' },
|
|
290
|
+
];
|
|
291
|
+
for (const { expected, operation, provider } of validOAuthStates) {
|
|
292
|
+
it(`accepts the ${operation} ${provider} OAuth state`, () => {
|
|
293
|
+
expect(v.safeParse(appwrite.rowSchemas.oauthStates, {
|
|
294
|
+
...validRows.oauthStates,
|
|
295
|
+
operation,
|
|
296
|
+
provider,
|
|
297
|
+
}).success).toBe(expected);
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
const invalidOAuthStates = [
|
|
301
|
+
{ description: 'an unknown operation', expected: false, value: { operation: 'UNKNOWN' } },
|
|
302
|
+
{ description: 'an unknown provider', expected: false, value: { provider: 'UNKNOWN' } },
|
|
303
|
+
{ description: 'a malformed return URL', expected: false, value: { returnUri: 'not-a-url' } },
|
|
304
|
+
{
|
|
305
|
+
description: 'an unapproved return destination',
|
|
306
|
+
expected: false,
|
|
307
|
+
value: { returnUri: 'https://attacker.example/onboarding/provider-selection' },
|
|
308
|
+
},
|
|
309
|
+
];
|
|
310
|
+
for (const { description, expected, value } of invalidOAuthStates) {
|
|
311
|
+
it(`rejects an OAuth state with ${description}`, () => {
|
|
312
|
+
expect(v.safeParse(appwrite.rowSchemas.oauthStates, { ...validRows.oauthStates, ...value }).success).toBe(expected);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
261
315
|
const invalidSequences = [
|
|
262
316
|
{ description: 'numeric', value: 1 },
|
|
263
317
|
{ description: 'empty', value: '' },
|
|
@@ -15,9 +15,10 @@ export declare const appwriteFunctions: {
|
|
|
15
15
|
requestSchema: v.StrictObjectSchema<{
|
|
16
16
|
readonly accountId: v.NonOptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.NonEmptyAction<string, undefined>, v.MaxLengthAction<string, number, undefined>, v.BrandAction<string, "AccountId">]>, undefined>;
|
|
17
17
|
readonly connection: v.VariantSchema<"kind", [v.StrictObjectSchema<{
|
|
18
|
+
readonly email: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>;
|
|
18
19
|
readonly kind: v.LiteralSchema<"OAUTH", undefined>;
|
|
19
20
|
readonly provider: v.PicklistSchema<["GMAIL", "OUTLOOK"], undefined>;
|
|
20
|
-
readonly
|
|
21
|
+
readonly returnUri: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/provider-selection", "https://app.staging.marcoapp.io/onboarding/provider-selection"], undefined>;
|
|
21
22
|
}, undefined>, v.StrictObjectSchema<{
|
|
22
23
|
readonly imap: v.StrictObjectSchema<{
|
|
23
24
|
readonly host: v.NonOptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.NonEmptyAction<string, undefined>, v.MaxLengthAction<string, number, undefined>]>, undefined>;
|
|
@@ -65,9 +66,10 @@ export declare const appwriteFunctions: {
|
|
|
65
66
|
path: "/accounts/connect";
|
|
66
67
|
requestSchema: v.StrictObjectSchema<{
|
|
67
68
|
readonly connection: v.VariantSchema<"kind", [v.StrictObjectSchema<{
|
|
69
|
+
readonly email: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>;
|
|
68
70
|
readonly kind: v.LiteralSchema<"OAUTH", undefined>;
|
|
69
71
|
readonly provider: v.PicklistSchema<["GMAIL", "OUTLOOK"], undefined>;
|
|
70
|
-
readonly
|
|
72
|
+
readonly returnUri: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/provider-selection", "https://app.staging.marcoapp.io/onboarding/provider-selection"], undefined>;
|
|
71
73
|
}, undefined>, v.StrictObjectSchema<{
|
|
72
74
|
readonly imap: v.StrictObjectSchema<{
|
|
73
75
|
readonly host: v.NonOptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.NonEmptyAction<string, undefined>, v.MaxLengthAction<string, number, undefined>]>, undefined>;
|
|
@@ -443,7 +445,7 @@ export declare const appwriteFunctions: {
|
|
|
443
445
|
}, undefined>;
|
|
444
446
|
context: "webhook";
|
|
445
447
|
method: "GET";
|
|
446
|
-
path: "/
|
|
448
|
+
path: "/v1/wh/oauth/callback";
|
|
447
449
|
requestSchema: v.StrictObjectSchema<{
|
|
448
450
|
readonly code: v.NonOptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.NonEmptyAction<string, undefined>, v.MaxLengthAction<string, number, undefined>]>, undefined>;
|
|
449
451
|
readonly state: v.NonOptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.NonEmptyAction<string, undefined>, v.MaxLengthAction<string, number, undefined>]>, undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../src/appwrite/functions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../src/appwrite/functions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAS5B,KAAK,uBAAuB,GAAG,eAAe,GAAG,UAAU,GAAG,SAAS,CAAA;AAsJvE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAWpB,CAAA;AAEV,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,iBAAiB,CAAC,WAAW,CAAC,CAAA;AACvF,YAAY,EAAE,uBAAuB,EAAE,CAAA;AACvC,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG,QAAQ,CAAA;AACnD,MAAM,MAAM,yBAAyB,CAAC,SAAS,SAAS,oBAAoB,IAAI,SAAS,SAAS,oBAAoB,GAClH,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,GACrD,KAAK,CAAA;AACT,MAAM,MAAM,qBAAqB,CAC/B,SAAS,SAAS,oBAAoB,EACtC,MAAM,SAAS,yBAAyB,CAAC,SAAS,CAAC,IACjD,SAAS,SAAS,oBAAoB,GACtC,MAAM,SAAS,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,GAClE,CAAC,OAAO,iBAAiB,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GACvD,KAAK,GACP,KAAK,CAAA;AACT,MAAM,MAAM,uBAAuB,CACjC,SAAS,SAAS,oBAAoB,EACtC,MAAM,SAAS,yBAAyB,CAAC,SAAS,CAAC,IACjD,qBAAqB,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS;IAAE,aAAa,EAAE,MAAM,OAAO,SAAS,CAAC,CAAC,aAAa,CAAA;CAAE,GACzG,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,GACtB,KAAK,CAAA;AACT,MAAM,MAAM,wBAAwB,CAClC,SAAS,SAAS,oBAAoB,EACtC,MAAM,SAAS,yBAAyB,CAAC,SAAS,CAAC,IACjD,qBAAqB,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS;IAAE,cAAc,EAAE,MAAM,OAAO,SAAS,CAAC,CAAC,aAAa,CAAA;CAAE,GAC1G,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,GACtB,KAAK,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as v from 'valibot';
|
|
2
|
+
import { oauth } from '../constants/oauth';
|
|
2
3
|
import { id } from '../schemas/id';
|
|
3
4
|
import { string } from '../schemas/string';
|
|
4
5
|
import { appwrite } from './appwrite';
|
|
@@ -29,9 +30,10 @@ const providerCredentialSchema = v.strictObject({
|
|
|
29
30
|
});
|
|
30
31
|
const connectionSchema = v.variant('kind', [
|
|
31
32
|
v.strictObject({
|
|
33
|
+
email: v.pipe(v.string(), v.email()),
|
|
32
34
|
kind: v.literal('OAUTH'),
|
|
33
35
|
provider: v.picklist(['GMAIL', 'OUTLOOK']),
|
|
34
|
-
|
|
36
|
+
returnUri: appwrite.oauth.returnUriSchema,
|
|
35
37
|
}),
|
|
36
38
|
v.strictObject({
|
|
37
39
|
imap: providerCredentialSchema,
|
|
@@ -85,7 +87,7 @@ const apiRoutes = {
|
|
|
85
87
|
oauthWebhook: createRoute({
|
|
86
88
|
context: 'webhook',
|
|
87
89
|
method: 'GET',
|
|
88
|
-
path:
|
|
90
|
+
path: oauth.redirectPath,
|
|
89
91
|
requestSchema: v.strictObject({
|
|
90
92
|
code: string.required(4096),
|
|
91
93
|
state: string.required(4096),
|
|
@@ -49,7 +49,14 @@ const routeFixtures = [
|
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
name: 'account connect',
|
|
52
|
-
request: {
|
|
52
|
+
request: {
|
|
53
|
+
connection: {
|
|
54
|
+
email: 'test-user@example.com',
|
|
55
|
+
kind: 'OAUTH',
|
|
56
|
+
provider: 'GMAIL',
|
|
57
|
+
returnUri: 'https://app.marcoapp.io/onboarding/provider-selection',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
53
60
|
response: {
|
|
54
61
|
accountId: 'account_1',
|
|
55
62
|
authorizationUrl: 'https://accounts.google.com/o/oauth2/auth',
|
|
@@ -119,7 +126,7 @@ describe('appwriteFunctions', () => {
|
|
|
119
126
|
{ context: 'authenticated', functionId: 'marco-api', method: 'PUT', path: '/accounts/connection' },
|
|
120
127
|
{ context: 'authenticated', functionId: 'marco-api', method: 'POST', path: '/push-tokens' },
|
|
121
128
|
{ context: 'authenticated', functionId: 'marco-api', method: 'DELETE', path: '/account/delete' },
|
|
122
|
-
{ context: 'webhook', functionId: 'marco-api', method: 'GET', path: '/
|
|
129
|
+
{ context: 'webhook', functionId: 'marco-api', method: 'GET', path: '/v1/wh/oauth/callback' },
|
|
123
130
|
{ context: 'internal', functionId: 'marco-worker', method: 'POST', path: '/' },
|
|
124
131
|
{ context: 'internal', functionId: 'marco-worker', method: 'POST', path: '/jobs/run' },
|
|
125
132
|
{ context: 'internal', functionId: 'marco-worker', method: 'POST', path: '/watchers/run' },
|
|
@@ -151,4 +158,55 @@ describe('appwriteFunctions', () => {
|
|
|
151
158
|
retryable: false,
|
|
152
159
|
}).success).toBe(false);
|
|
153
160
|
});
|
|
161
|
+
const invalidOAuthConnections = [
|
|
162
|
+
{
|
|
163
|
+
connection: {
|
|
164
|
+
kind: 'OAUTH',
|
|
165
|
+
provider: 'GMAIL',
|
|
166
|
+
returnUri: 'https://app.marcoapp.io/onboarding/provider-selection',
|
|
167
|
+
},
|
|
168
|
+
description: 'a missing mailbox email',
|
|
169
|
+
expected: false,
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
connection: {
|
|
173
|
+
email: 'not-an-email',
|
|
174
|
+
kind: 'OAUTH',
|
|
175
|
+
provider: 'GMAIL',
|
|
176
|
+
returnUri: 'https://app.marcoapp.io/onboarding/provider-selection',
|
|
177
|
+
},
|
|
178
|
+
description: 'a malformed mailbox email',
|
|
179
|
+
expected: false,
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
connection: {
|
|
183
|
+
email: 'test-user@example.com',
|
|
184
|
+
kind: 'OAUTH',
|
|
185
|
+
provider: 'GMAIL',
|
|
186
|
+
returnUri: 'https://attacker.example/onboarding/provider-selection',
|
|
187
|
+
},
|
|
188
|
+
description: 'an unapproved return destination',
|
|
189
|
+
expected: false,
|
|
190
|
+
},
|
|
191
|
+
];
|
|
192
|
+
const oauthConnectionRoutes = [
|
|
193
|
+
{
|
|
194
|
+
description: 'connect',
|
|
195
|
+
includesAccountId: false,
|
|
196
|
+
requestSchema: appwriteFunctions.api.routes.accountsConnect.requestSchema,
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
description: 'replacement',
|
|
200
|
+
includesAccountId: true,
|
|
201
|
+
requestSchema: appwriteFunctions.api.routes.accountConnection.requestSchema,
|
|
202
|
+
},
|
|
203
|
+
];
|
|
204
|
+
for (const { connection, description, expected } of invalidOAuthConnections) {
|
|
205
|
+
for (const { description: routeDescription, includesAccountId, requestSchema } of oauthConnectionRoutes) {
|
|
206
|
+
it(`rejects ${routeDescription} OAuth connection with ${description}`, () => {
|
|
207
|
+
const request = includesAccountId ? { accountId: 'account_1', connection } : { connection };
|
|
208
|
+
expect(v.safeParse(requestSchema, request).success).toBe(expected);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
154
212
|
});
|
|
@@ -2,6 +2,10 @@ import type { SubscriptionTier } from './types';
|
|
|
2
2
|
export type MarcoEnvironment = 'production' | 'staging' | 'development';
|
|
3
3
|
export declare const MARCO_ENV: MarcoEnvironment;
|
|
4
4
|
type MarcoPublicConfig = {
|
|
5
|
+
appwrite: {
|
|
6
|
+
endpoint: string;
|
|
7
|
+
projectId: string;
|
|
8
|
+
};
|
|
5
9
|
marco: {
|
|
6
10
|
api: {
|
|
7
11
|
baseUrl: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marcoPublicConfig.d.ts","sourceRoot":"","sources":["../src/marcoPublicConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,SAAS,GAAG,aAAa,CAAA;AAEvE,eAAO,MAAM,SAAS,kBAGP,CAAA;AAEf,KAAK,iBAAiB,GAAG;IACvB,KAAK,EAAE;QACL,GAAG,EAAE;YACH,OAAO,EAAE,MAAM,CAAA;SAChB,CAAA;QACD,GAAG,EAAE;YACH,OAAO,EAAE,MAAM,CAAA;SAChB,CAAA;QACD,GAAG,EAAE;YACH,OAAO,EAAE,MAAM,CAAA;YACf,UAAU,EAAE,MAAM,CAAA;SACnB,CAAA;QACD,EAAE,EAAE;YACF,KAAK,EAAE,MAAM,CAAA;YACb,IAAI,EAAE,MAAM,CAAA;YACZ,GAAG,EAAE,MAAM,CAAA;SACZ,CAAA;KACF,CAAA;IACD,KAAK,EAAE;QACL,MAAM,EAAE;YACN,QAAQ,EAAE,MAAM,CAAA;SACjB,CAAA;QACD,OAAO,EAAE;YACP,QAAQ,EAAE,MAAM,CAAA;YAChB,QAAQ,EAAE,MAAM,CAAA;SACjB,CAAA;KACF,CAAA;IACD,MAAM,EAAE;QACN,QAAQ,EAAE;aACP,GAAG,IAAI,gBAAgB,GAAG;gBACzB,EAAE,EAAE,MAAM,CAAA;gBACV,QAAQ,EAAE;oBACR,OAAO,EAAE,MAAM,CAAA;oBACf,MAAM,EAAE,MAAM,CAAA;iBACf,CAAA;aACF;SACF,CAAA;KACF,CAAA;IACD,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF,CAAA;
|
|
1
|
+
{"version":3,"file":"marcoPublicConfig.d.ts","sourceRoot":"","sources":["../src/marcoPublicConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,SAAS,GAAG,aAAa,CAAA;AAEvE,eAAO,MAAM,SAAS,kBAGP,CAAA;AAEf,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;IACD,KAAK,EAAE;QACL,GAAG,EAAE;YACH,OAAO,EAAE,MAAM,CAAA;SAChB,CAAA;QACD,GAAG,EAAE;YACH,OAAO,EAAE,MAAM,CAAA;SAChB,CAAA;QACD,GAAG,EAAE;YACH,OAAO,EAAE,MAAM,CAAA;YACf,UAAU,EAAE,MAAM,CAAA;SACnB,CAAA;QACD,EAAE,EAAE;YACF,KAAK,EAAE,MAAM,CAAA;YACb,IAAI,EAAE,MAAM,CAAA;YACZ,GAAG,EAAE,MAAM,CAAA;SACZ,CAAA;KACF,CAAA;IACD,KAAK,EAAE;QACL,MAAM,EAAE;YACN,QAAQ,EAAE,MAAM,CAAA;SACjB,CAAA;QACD,OAAO,EAAE;YACP,QAAQ,EAAE,MAAM,CAAA;YAChB,QAAQ,EAAE,MAAM,CAAA;SACjB,CAAA;KACF,CAAA;IACD,MAAM,EAAE;QACN,QAAQ,EAAE;aACP,GAAG,IAAI,gBAAgB,GAAG;gBACzB,EAAE,EAAE,MAAM,CAAA;gBACV,QAAQ,EAAE;oBACR,OAAO,EAAE,MAAM,CAAA;oBACf,MAAM,EAAE,MAAM,CAAA;iBACf,CAAA;aACF;SACF,CAAA;KACF,CAAA;IACD,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF,CAAA;AA+ID,eAAO,MAAM,iBAAiB,SAAS,gBAAgB,sBAAmC,CAAA"}
|
|
@@ -3,6 +3,10 @@ export const MARCO_ENV = process.env.MARCO_ENV ||
|
|
|
3
3
|
'development';
|
|
4
4
|
const configMap = {
|
|
5
5
|
development: {
|
|
6
|
+
appwrite: {
|
|
7
|
+
endpoint: 'https://nyc.cloud.appwrite.io/v1',
|
|
8
|
+
projectId: 'marco',
|
|
9
|
+
},
|
|
6
10
|
marco: {
|
|
7
11
|
api: {
|
|
8
12
|
baseUrl: 'https://api.staging.marcoapp.io',
|
|
@@ -45,6 +49,10 @@ const configMap = {
|
|
|
45
49
|
},
|
|
46
50
|
},
|
|
47
51
|
production: {
|
|
52
|
+
appwrite: {
|
|
53
|
+
endpoint: 'https://nyc.cloud.appwrite.io/v1',
|
|
54
|
+
projectId: 'marco',
|
|
55
|
+
},
|
|
48
56
|
marco: {
|
|
49
57
|
api: {
|
|
50
58
|
baseUrl: 'https://api.marcoapp.io',
|
|
@@ -87,6 +95,10 @@ const configMap = {
|
|
|
87
95
|
},
|
|
88
96
|
},
|
|
89
97
|
staging: {
|
|
98
|
+
appwrite: {
|
|
99
|
+
endpoint: 'https://nyc.cloud.appwrite.io/v1',
|
|
100
|
+
projectId: 'marco',
|
|
101
|
+
},
|
|
90
102
|
marco: {
|
|
91
103
|
api: {
|
|
92
104
|
baseUrl: 'https://api.staging.marcoapp.io',
|