@seeka-labs/cli-apps 2.0.13-alpha.0 → 2.0.19-alpha.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/LICENSE +19 -19
- package/dist/index.js +1 -1
- package/dist/index.js.map +2 -2
- package/dist/init-template/.gitlab-ci.yml +46 -46
- package/dist/init-template/.yarnrc.yml +8 -0
- package/dist/init-template/README.md +6 -6
- package/dist/init-template/app/browser/jest.config.js +11 -11
- package/dist/init-template/app/browser/package.json +40 -40
- package/dist/init-template/app/browser/scripts/esbuild/build-browser-plugin.mjs +110 -110
- package/dist/init-template/app/browser/scripts/esbuild/plugins/importAsGlobals.mjs +38 -38
- package/dist/init-template/app/browser/src/browser.ts +12 -12
- package/dist/init-template/app/browser/src/plugin/index.test.ts +6 -6
- package/dist/init-template/app/browser/src/plugin/index.ts +47 -47
- package/dist/init-template/app/browser/tsconfig.json +34 -34
- package/dist/init-template/app/server-azure-function/.eslintrc.cjs +10 -10
- package/dist/init-template/app/server-azure-function/.funcignore +21 -21
- package/dist/init-template/app/server-azure-function/README.md +104 -104
- package/dist/init-template/app/server-azure-function/host.json +19 -19
- package/dist/init-template/app/server-azure-function/local.settings.example.json +25 -25
- package/dist/init-template/app/server-azure-function/package.json +52 -52
- package/dist/init-template/app/server-azure-function/scripts/ngrok.js +27 -27
- package/dist/init-template/app/server-azure-function/src/functions/healthCheck.ts +13 -13
- package/dist/init-template/app/server-azure-function/src/functions/pollingExample.ts +39 -39
- package/dist/init-template/app/server-azure-function/src/functions/queueExample.ts +66 -66
- package/dist/init-template/app/server-azure-function/src/functions/seekaAppWebhook.ts +235 -235
- package/dist/init-template/app/server-azure-function/src/lib/browser/index.ts +54 -54
- package/dist/init-template/app/server-azure-function/src/lib/jobs/index.ts +95 -95
- package/dist/init-template/app/server-azure-function/src/lib/logging/index.ts +92 -92
- package/dist/init-template/app/server-azure-function/src/lib/models/index.ts +6 -6
- package/dist/init-template/app/server-azure-function/src/lib/services/index.ts +40 -40
- package/dist/init-template/app/server-azure-function/src/lib/state/redis/index.ts +96 -96
- package/dist/init-template/app/server-azure-function/src/lib/state/seeka/installations.ts +64 -64
- package/dist/init-template/app/server-azure-function/tsconfig.json +17 -17
- package/dist/init-template/package.json +1 -1
- package/dist/init-template/tsconfig.json +25 -25
- package/package.json +2 -2
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
import winston from 'winston';
|
|
2
|
-
|
|
3
|
-
import { app, InvocationContext, Timer } from '@azure/functions';
|
|
4
|
-
import { QueueClient } from '@azure/storage-queue';
|
|
5
|
-
|
|
6
|
-
import { jobNames, queueNames, triggerBackgroundJobWithQueue } from '../lib/jobs';
|
|
7
|
-
import { backgroundJobLogger } from '../lib/logging';
|
|
8
|
-
import { startServices } from '../lib/services';
|
|
9
|
-
import { listInstallations } from '../lib/state/seeka/installations';
|
|
10
|
-
|
|
11
|
-
// https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer?tabs=python-v2%2Cisolated-process%2Cnodejs-v4&pivots=programming-language-typescript
|
|
12
|
-
app.timer('pollingExample', {
|
|
13
|
-
schedule: '0 0 * * * *', // every 1 hour
|
|
14
|
-
handler: pollingExample
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
export async function pollingExample(myTimer: Timer, context: InvocationContext): Promise<void> {
|
|
18
|
-
const logger = backgroundJobLogger(jobNames.pollingExample, undefined, context);
|
|
19
|
-
|
|
20
|
-
logger.profile(`job.${jobNames.pollingExample}`)
|
|
21
|
-
logger.debug('Received request to trigger scheduled job');
|
|
22
|
-
|
|
23
|
-
await startServices(logger);
|
|
24
|
-
|
|
25
|
-
const allInstallations = await listInstallations(logger);
|
|
26
|
-
logger.verbose(`Triggering background job for ${allInstallations.length} installations`)
|
|
27
|
-
|
|
28
|
-
const queueClient = new QueueClient(process.env.AzureWebJobsStorage as string, queueNames.queueItemExampleQueueName);
|
|
29
|
-
const promises = allInstallations.map(installation => triggerBackgroundJobWithQueue(queueClient, { ...installation, causationId: context.invocationId, correlationId: context.invocationId }, logger))
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
await Promise.all(promises);
|
|
33
|
-
}
|
|
34
|
-
catch (err) {
|
|
35
|
-
logger.error('Error triggering background jobs', { ex: winston.exceptions.getAllInfo(err) })
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
logger.profile(`job.${jobNames.pollingExample}`)
|
|
39
|
-
}
|
|
1
|
+
import winston from 'winston';
|
|
2
|
+
|
|
3
|
+
import { app, InvocationContext, Timer } from '@azure/functions';
|
|
4
|
+
import { QueueClient } from '@azure/storage-queue';
|
|
5
|
+
|
|
6
|
+
import { jobNames, queueNames, triggerBackgroundJobWithQueue } from '../lib/jobs';
|
|
7
|
+
import { backgroundJobLogger } from '../lib/logging';
|
|
8
|
+
import { startServices } from '../lib/services';
|
|
9
|
+
import { listInstallations } from '../lib/state/seeka/installations';
|
|
10
|
+
|
|
11
|
+
// https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer?tabs=python-v2%2Cisolated-process%2Cnodejs-v4&pivots=programming-language-typescript
|
|
12
|
+
app.timer('pollingExample', {
|
|
13
|
+
schedule: '0 0 * * * *', // every 1 hour
|
|
14
|
+
handler: pollingExample
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export async function pollingExample(myTimer: Timer, context: InvocationContext): Promise<void> {
|
|
18
|
+
const logger = backgroundJobLogger(jobNames.pollingExample, undefined, context);
|
|
19
|
+
|
|
20
|
+
logger.profile(`job.${jobNames.pollingExample}`)
|
|
21
|
+
logger.debug('Received request to trigger scheduled job');
|
|
22
|
+
|
|
23
|
+
await startServices(logger);
|
|
24
|
+
|
|
25
|
+
const allInstallations = await listInstallations(logger);
|
|
26
|
+
logger.verbose(`Triggering background job for ${allInstallations.length} installations`)
|
|
27
|
+
|
|
28
|
+
const queueClient = new QueueClient(process.env.AzureWebJobsStorage as string, queueNames.queueItemExampleQueueName);
|
|
29
|
+
const promises = allInstallations.map(installation => triggerBackgroundJobWithQueue(queueClient, { ...installation, causationId: context.invocationId, correlationId: context.invocationId }, logger))
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
await Promise.all(promises);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
logger.error('Error triggering background jobs', { ex: winston.exceptions.getAllInfo(err) })
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
logger.profile(`job.${jobNames.pollingExample}`)
|
|
39
|
+
}
|
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
import winston from 'winston';
|
|
2
|
-
|
|
3
|
-
import { app, InvocationContext } from '@azure/functions';
|
|
4
|
-
|
|
5
|
-
import { BackgroundJobRequestContext, deserialiseQueuePayload, queueNames, sendQueueMessageToPoisonQueue } from '../lib/jobs';
|
|
6
|
-
import { backgroundJobLogger } from '../lib/logging';
|
|
7
|
-
import { startServices } from '../lib/services';
|
|
8
|
-
import { groupBy } from 'lodash';
|
|
9
|
-
import { SeekaAppInstallState, tryGetInstallation } from '../lib/state/seeka/installations';
|
|
10
|
-
import { SeekaActivityAcceptedWebhookContent } from '@seeka-labs/sdk-apps-server';
|
|
11
|
-
|
|
12
|
-
app.storageQueue('queueExample', {
|
|
13
|
-
queueName: queueNames.queueItemExampleQueueName,
|
|
14
|
-
connection: 'AzureWebJobsStorage',
|
|
15
|
-
handler: queueExample
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
export interface MyQueueItem extends BackgroundJobRequestContext {
|
|
19
|
-
items: SeekaActivityAcceptedWebhookContent[];
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export async function queueExample(queueItem: any, context: InvocationContext): Promise<void> {
|
|
23
|
-
const logger = backgroundJobLogger(queueNames.queueItemExampleQueueName, undefined, context);
|
|
24
|
-
logger.profile(`queue.${queueNames.queueItemExampleQueueName}`)
|
|
25
|
-
try {
|
|
26
|
-
// queueItem can either be a single item or an array of items
|
|
27
|
-
const payload = deserialiseQueuePayload<MyQueueItem>(queueItem, logger);
|
|
28
|
-
|
|
29
|
-
// Group by applicationInstallId
|
|
30
|
-
const grouped = groupBy(payload, e => e.applicationInstallId);
|
|
31
|
-
|
|
32
|
-
logger.verbose('Received queue batch to handle queue message', { batchSize: payload.length });
|
|
33
|
-
|
|
34
|
-
// Process each group
|
|
35
|
-
await startServices(logger);
|
|
36
|
-
for (const [applicationInstallId, items] of Object.entries(grouped)) {
|
|
37
|
-
if (items.length === 0) {
|
|
38
|
-
logger.warn('No items to process for applicationInstallId', { applicationInstallId });
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
const thisLogger = backgroundJobLogger(queueNames.queueItemExampleQueueName, items[0], context);
|
|
42
|
-
try {
|
|
43
|
-
const installation = await tryGetInstallation(applicationInstallId, true, thisLogger) as SeekaAppInstallState;
|
|
44
|
-
|
|
45
|
-
// Execute sync
|
|
46
|
-
// const batchItems = items.flatMap(e => e.items || []).filter(Boolean)
|
|
47
|
-
// await executeLongRunningTask(batchItems, logger);
|
|
48
|
-
}
|
|
49
|
-
catch (err) {
|
|
50
|
-
thisLogger.error('Error handling queue item to handle queue message', { ex: winston.exceptions.getAllInfo(err) })
|
|
51
|
-
await sendQueueMessageToPoisonQueue(queueNames.queueItemExampleQueueName, {
|
|
52
|
-
...items[0],
|
|
53
|
-
causationId: items[0].causationId,
|
|
54
|
-
correlationId: context.invocationId,
|
|
55
|
-
rows: items.flatMap(e => e.items || []).filter(Boolean)
|
|
56
|
-
} as MyQueueItem, thisLogger);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
catch (err) {
|
|
61
|
-
logger.error('Error handling queue item to handle queue message', { ex: winston.exceptions.getAllInfo(err) })
|
|
62
|
-
throw err; // Will retry based on host.json > extensions.queues.maxDequeueCount and then push to poison queue
|
|
63
|
-
}
|
|
64
|
-
finally {
|
|
65
|
-
logger.profile(`queue.${queueNames.queueItemExampleQueueName}`)
|
|
66
|
-
}
|
|
1
|
+
import winston from 'winston';
|
|
2
|
+
|
|
3
|
+
import { app, InvocationContext } from '@azure/functions';
|
|
4
|
+
|
|
5
|
+
import { BackgroundJobRequestContext, deserialiseQueuePayload, queueNames, sendQueueMessageToPoisonQueue } from '../lib/jobs';
|
|
6
|
+
import { backgroundJobLogger } from '../lib/logging';
|
|
7
|
+
import { startServices } from '../lib/services';
|
|
8
|
+
import { groupBy } from 'lodash';
|
|
9
|
+
import { SeekaAppInstallState, tryGetInstallation } from '../lib/state/seeka/installations';
|
|
10
|
+
import { SeekaActivityAcceptedWebhookContent } from '@seeka-labs/sdk-apps-server';
|
|
11
|
+
|
|
12
|
+
app.storageQueue('queueExample', {
|
|
13
|
+
queueName: queueNames.queueItemExampleQueueName,
|
|
14
|
+
connection: 'AzureWebJobsStorage',
|
|
15
|
+
handler: queueExample
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export interface MyQueueItem extends BackgroundJobRequestContext {
|
|
19
|
+
items: SeekaActivityAcceptedWebhookContent[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function queueExample(queueItem: any, context: InvocationContext): Promise<void> {
|
|
23
|
+
const logger = backgroundJobLogger(queueNames.queueItemExampleQueueName, undefined, context);
|
|
24
|
+
logger.profile(`queue.${queueNames.queueItemExampleQueueName}`)
|
|
25
|
+
try {
|
|
26
|
+
// queueItem can either be a single item or an array of items
|
|
27
|
+
const payload = deserialiseQueuePayload<MyQueueItem>(queueItem, logger);
|
|
28
|
+
|
|
29
|
+
// Group by applicationInstallId
|
|
30
|
+
const grouped = groupBy(payload, e => e.applicationInstallId);
|
|
31
|
+
|
|
32
|
+
logger.verbose('Received queue batch to handle queue message', { batchSize: payload.length });
|
|
33
|
+
|
|
34
|
+
// Process each group
|
|
35
|
+
await startServices(logger);
|
|
36
|
+
for (const [applicationInstallId, items] of Object.entries(grouped)) {
|
|
37
|
+
if (items.length === 0) {
|
|
38
|
+
logger.warn('No items to process for applicationInstallId', { applicationInstallId });
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const thisLogger = backgroundJobLogger(queueNames.queueItemExampleQueueName, items[0], context);
|
|
42
|
+
try {
|
|
43
|
+
const installation = await tryGetInstallation(applicationInstallId, true, thisLogger) as SeekaAppInstallState;
|
|
44
|
+
|
|
45
|
+
// Execute sync
|
|
46
|
+
// const batchItems = items.flatMap(e => e.items || []).filter(Boolean)
|
|
47
|
+
// await executeLongRunningTask(batchItems, logger);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
thisLogger.error('Error handling queue item to handle queue message', { ex: winston.exceptions.getAllInfo(err) })
|
|
51
|
+
await sendQueueMessageToPoisonQueue(queueNames.queueItemExampleQueueName, {
|
|
52
|
+
...items[0],
|
|
53
|
+
causationId: items[0].causationId,
|
|
54
|
+
correlationId: context.invocationId,
|
|
55
|
+
rows: items.flatMap(e => e.items || []).filter(Boolean)
|
|
56
|
+
} as MyQueueItem, thisLogger);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
logger.error('Error handling queue item to handle queue message', { ex: winston.exceptions.getAllInfo(err) })
|
|
62
|
+
throw err; // Will retry based on host.json > extensions.queues.maxDequeueCount and then push to poison queue
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
logger.profile(`queue.${queueNames.queueItemExampleQueueName}`)
|
|
66
|
+
}
|
|
67
67
|
}
|