@seeka-labs/cli-apps 2.0.7-rc.2 → 2.0.10-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 +0 -0
- package/dist/index.js.map +1 -1
- package/dist/init-template/.gitlab-ci.yml +46 -46
- package/dist/init-template/README.md +6 -6
- package/dist/init-template/app/browser/package.json +40 -40
- 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/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/lib/jobs/index.ts +95 -95
- package/dist/init-template/app/server-azure-function/src/lib/services/index.ts +40 -40
- package/dist/init-template/app/server-azure-function/tsconfig.json +17 -17
- package/dist/init-template/package.json +28 -28
- package/dist/init-template/tsconfig.json +25 -25
- package/package.json +2 -2
- package/dist/init-template/.yarnrc.yml +0 -8
|
@@ -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
|
}
|
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
import { QueueClient } from '@azure/storage-queue';
|
|
2
|
-
import { isArray } from 'lodash';
|
|
3
|
-
import type { Logger } from 'winston';
|
|
4
|
-
import winston from 'winston';
|
|
5
|
-
|
|
6
|
-
export interface BackgroundJobRequestContext {
|
|
7
|
-
organisationId?: string;
|
|
8
|
-
organisationBrandId?: string;
|
|
9
|
-
applicationInstallId?: string;
|
|
10
|
-
causationId: string
|
|
11
|
-
correlationId: string
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const signatureHeaderName = 'x-signature-hmac';
|
|
15
|
-
export const apiKeyHeaderName = 'x-api-key';
|
|
16
|
-
|
|
17
|
-
export const jobNames = {
|
|
18
|
-
pollingExample: 'polling-example',
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const queueNames = {
|
|
22
|
-
queueItemExampleQueueName: 'sample-queue-name'
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const triggerBackgroundJob = async (queueName: string, context: BackgroundJobRequestContext, logger: Logger): Promise<void> => {
|
|
26
|
-
const queueClient = new QueueClient(process.env.AzureWebJobsStorage as string, queueName);
|
|
27
|
-
return triggerBackgroundJobWithQueue(queueClient, context, logger);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const serialiseQueuePayload = (payload: unknown): string => {
|
|
31
|
-
const jsonString = JSON.stringify(payload)
|
|
32
|
-
return Buffer.from(jsonString).toString('base64')
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export const deserialiseQueuePayload = <TPayload>(queueItem: any, logger: Logger): TPayload[] => {
|
|
36
|
-
try {
|
|
37
|
-
if (typeof queueItem !== 'string') {
|
|
38
|
-
if (isArray(queueItem)) {
|
|
39
|
-
return queueItem
|
|
40
|
-
}
|
|
41
|
-
return [queueItem]
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
const jsonString = Buffer.from(queueItem, 'base64').toString()
|
|
45
|
-
const parsed = JSON.parse(jsonString);
|
|
46
|
-
|
|
47
|
-
if (isArray(parsed)) {
|
|
48
|
-
return parsed
|
|
49
|
-
}
|
|
50
|
-
return [parsed]
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
catch (err) {
|
|
54
|
-
logger.error('Failed to deserialise queue payload', { ex: winston.exceptions.getAllInfo(err), queueItem });
|
|
55
|
-
throw new Error(`Failed to deserialise queue payload`);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export const triggerBackgroundJobWithQueue = async (queueClient: QueueClient, context: BackgroundJobRequestContext, logger: Logger): Promise<void> => {
|
|
60
|
-
const body = {
|
|
61
|
-
...context
|
|
62
|
-
}
|
|
63
|
-
const bodyStr = serialiseQueuePayload(body);
|
|
64
|
-
|
|
65
|
-
const response = await queueClient.sendMessage(bodyStr, { messageTimeToLive: -1 });
|
|
66
|
-
|
|
67
|
-
if (response.errorCode) {
|
|
68
|
-
const { requestId, date, errorCode } = response;
|
|
69
|
-
logger.error("Failed to trigger background job", { body, requestId, date, errorCode })
|
|
70
|
-
throw new Error(`Failed to trigger background job: ${response.errorCode}`);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
logger.debug("Background job triggered", { body, messageId: response.messageId, context })
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export const sendQueueMessageToPoisonQueue = async (queueName: string, context: BackgroundJobRequestContext, logger: Logger): Promise<void> => {
|
|
78
|
-
const body = {
|
|
79
|
-
...context
|
|
80
|
-
}
|
|
81
|
-
const bodyStr = serialiseQueuePayload(body);
|
|
82
|
-
|
|
83
|
-
// https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-queue-trigger?tabs=python-v2%2Cisolated-process%2Cnodejs-v4%2Cextensionv5&pivots=programming-language-typescript#poison-messages
|
|
84
|
-
const queueClient = new QueueClient(process.env.AzureWebJobsStorage as string, `${queueName}-poison`);
|
|
85
|
-
|
|
86
|
-
const response = await queueClient.sendMessage(bodyStr, { messageTimeToLive: -1 });
|
|
87
|
-
|
|
88
|
-
if (response.errorCode) {
|
|
89
|
-
const { requestId, date, errorCode } = response;
|
|
90
|
-
logger.error("Failed to push to poison queue", { body, requestId, date, errorCode })
|
|
91
|
-
throw new Error(`Failed to push to poison queue: ${response.errorCode}`);
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
logger.verbose("Message pushed to poison queue", { body, messageId: response.messageId, context })
|
|
95
|
-
}
|
|
1
|
+
import { QueueClient } from '@azure/storage-queue';
|
|
2
|
+
import { isArray } from 'lodash';
|
|
3
|
+
import type { Logger } from 'winston';
|
|
4
|
+
import winston from 'winston';
|
|
5
|
+
|
|
6
|
+
export interface BackgroundJobRequestContext {
|
|
7
|
+
organisationId?: string;
|
|
8
|
+
organisationBrandId?: string;
|
|
9
|
+
applicationInstallId?: string;
|
|
10
|
+
causationId: string
|
|
11
|
+
correlationId: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const signatureHeaderName = 'x-signature-hmac';
|
|
15
|
+
export const apiKeyHeaderName = 'x-api-key';
|
|
16
|
+
|
|
17
|
+
export const jobNames = {
|
|
18
|
+
pollingExample: 'polling-example',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const queueNames = {
|
|
22
|
+
queueItemExampleQueueName: 'sample-queue-name'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const triggerBackgroundJob = async (queueName: string, context: BackgroundJobRequestContext, logger: Logger): Promise<void> => {
|
|
26
|
+
const queueClient = new QueueClient(process.env.AzureWebJobsStorage as string, queueName);
|
|
27
|
+
return triggerBackgroundJobWithQueue(queueClient, context, logger);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const serialiseQueuePayload = (payload: unknown): string => {
|
|
31
|
+
const jsonString = JSON.stringify(payload)
|
|
32
|
+
return Buffer.from(jsonString).toString('base64')
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const deserialiseQueuePayload = <TPayload>(queueItem: any, logger: Logger): TPayload[] => {
|
|
36
|
+
try {
|
|
37
|
+
if (typeof queueItem !== 'string') {
|
|
38
|
+
if (isArray(queueItem)) {
|
|
39
|
+
return queueItem
|
|
40
|
+
}
|
|
41
|
+
return [queueItem]
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const jsonString = Buffer.from(queueItem, 'base64').toString()
|
|
45
|
+
const parsed = JSON.parse(jsonString);
|
|
46
|
+
|
|
47
|
+
if (isArray(parsed)) {
|
|
48
|
+
return parsed
|
|
49
|
+
}
|
|
50
|
+
return [parsed]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
logger.error('Failed to deserialise queue payload', { ex: winston.exceptions.getAllInfo(err), queueItem });
|
|
55
|
+
throw new Error(`Failed to deserialise queue payload`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const triggerBackgroundJobWithQueue = async (queueClient: QueueClient, context: BackgroundJobRequestContext, logger: Logger): Promise<void> => {
|
|
60
|
+
const body = {
|
|
61
|
+
...context
|
|
62
|
+
}
|
|
63
|
+
const bodyStr = serialiseQueuePayload(body);
|
|
64
|
+
|
|
65
|
+
const response = await queueClient.sendMessage(bodyStr, { messageTimeToLive: -1 });
|
|
66
|
+
|
|
67
|
+
if (response.errorCode) {
|
|
68
|
+
const { requestId, date, errorCode } = response;
|
|
69
|
+
logger.error("Failed to trigger background job", { body, requestId, date, errorCode })
|
|
70
|
+
throw new Error(`Failed to trigger background job: ${response.errorCode}`);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
logger.debug("Background job triggered", { body, messageId: response.messageId, context })
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export const sendQueueMessageToPoisonQueue = async (queueName: string, context: BackgroundJobRequestContext, logger: Logger): Promise<void> => {
|
|
78
|
+
const body = {
|
|
79
|
+
...context
|
|
80
|
+
}
|
|
81
|
+
const bodyStr = serialiseQueuePayload(body);
|
|
82
|
+
|
|
83
|
+
// https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-queue-trigger?tabs=python-v2%2Cisolated-process%2Cnodejs-v4%2Cextensionv5&pivots=programming-language-typescript#poison-messages
|
|
84
|
+
const queueClient = new QueueClient(process.env.AzureWebJobsStorage as string, `${queueName}-poison`);
|
|
85
|
+
|
|
86
|
+
const response = await queueClient.sendMessage(bodyStr, { messageTimeToLive: -1 });
|
|
87
|
+
|
|
88
|
+
if (response.errorCode) {
|
|
89
|
+
const { requestId, date, errorCode } = response;
|
|
90
|
+
logger.error("Failed to push to poison queue", { body, requestId, date, errorCode })
|
|
91
|
+
throw new Error(`Failed to push to poison queue: ${response.errorCode}`);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
logger.verbose("Message pushed to poison queue", { body, messageId: response.messageId, context })
|
|
95
|
+
}
|
|
96
96
|
}
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import winston, { Logger } from 'winston';
|
|
2
|
-
|
|
3
|
-
import { connect, disconnect, isConnected } from '../state/redis';
|
|
4
|
-
|
|
5
|
-
export const startServices = async (logger: Logger) => {
|
|
6
|
-
logger.debug(`Trying to connect to Redis - ${process.env.REDIS_CONNECTION_HOST}`)
|
|
7
|
-
try {
|
|
8
|
-
if (isConnected()) {
|
|
9
|
-
logger.verbose(`Redis already connected - ${process.env.REDIS_CONNECTION_HOST}`)
|
|
10
|
-
}
|
|
11
|
-
else {
|
|
12
|
-
logger.profile('service.redis.connect')
|
|
13
|
-
await connect();
|
|
14
|
-
logger.profile('service.redis.connect')
|
|
15
|
-
logger.debug(`Redis connected - ${process.env.REDIS_CONNECTION_HOST}`)
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
catch (err) {
|
|
19
|
-
logger.error(`Failed to connect to Redis - ${process.env.REDIS_CONNECTION_HOST}`, { ex: winston.exceptions.getAllInfo(err) })
|
|
20
|
-
throw err;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const stopServices = async (logger: Logger) => {
|
|
25
|
-
logger.debug(`Trying to disconnect from Redis - ${process.env.REDIS_CONNECTION_HOST}`)
|
|
26
|
-
try {
|
|
27
|
-
if (isConnected() === false) {
|
|
28
|
-
logger.verbose(`Redis already disconnected - ${process.env.REDIS_CONNECTION_HOST}`)
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
logger.profile('service.redis.disconnect')
|
|
32
|
-
await disconnect();
|
|
33
|
-
logger.profile('service.redis.disconnect')
|
|
34
|
-
logger.verbose(`Redis disconnected - ${process.env.REDIS_CONNECTION_HOST}`)
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
catch (err) {
|
|
38
|
-
logger.error(`Failed to disconnect from Redis - ${process.env.REDIS_CONNECTION_HOST}`, { ex: winston.exceptions.getAllInfo(err) })
|
|
39
|
-
throw err;
|
|
40
|
-
}
|
|
1
|
+
import winston, { Logger } from 'winston';
|
|
2
|
+
|
|
3
|
+
import { connect, disconnect, isConnected } from '../state/redis';
|
|
4
|
+
|
|
5
|
+
export const startServices = async (logger: Logger) => {
|
|
6
|
+
logger.debug(`Trying to connect to Redis - ${process.env.REDIS_CONNECTION_HOST}`)
|
|
7
|
+
try {
|
|
8
|
+
if (isConnected()) {
|
|
9
|
+
logger.verbose(`Redis already connected - ${process.env.REDIS_CONNECTION_HOST}`)
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
logger.profile('service.redis.connect')
|
|
13
|
+
await connect();
|
|
14
|
+
logger.profile('service.redis.connect')
|
|
15
|
+
logger.debug(`Redis connected - ${process.env.REDIS_CONNECTION_HOST}`)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
logger.error(`Failed to connect to Redis - ${process.env.REDIS_CONNECTION_HOST}`, { ex: winston.exceptions.getAllInfo(err) })
|
|
20
|
+
throw err;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const stopServices = async (logger: Logger) => {
|
|
25
|
+
logger.debug(`Trying to disconnect from Redis - ${process.env.REDIS_CONNECTION_HOST}`)
|
|
26
|
+
try {
|
|
27
|
+
if (isConnected() === false) {
|
|
28
|
+
logger.verbose(`Redis already disconnected - ${process.env.REDIS_CONNECTION_HOST}`)
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
logger.profile('service.redis.disconnect')
|
|
32
|
+
await disconnect();
|
|
33
|
+
logger.profile('service.redis.disconnect')
|
|
34
|
+
logger.verbose(`Redis disconnected - ${process.env.REDIS_CONNECTION_HOST}`)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
logger.error(`Failed to disconnect from Redis - ${process.env.REDIS_CONNECTION_HOST}`, { ex: winston.exceptions.getAllInfo(err) })
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
41
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"allowJs": true,
|
|
4
|
-
"skipLibCheck": true,
|
|
5
|
-
"strict": false,
|
|
6
|
-
"esModuleInterop": true,
|
|
7
|
-
"outDir": "dist",
|
|
8
|
-
"rootDir": ".",
|
|
9
|
-
"sourceMap": true,
|
|
10
|
-
"module": "CommonJS",
|
|
11
|
-
"target": "ES6",
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"isolatedModules": false,
|
|
14
|
-
},
|
|
15
|
-
"include": [
|
|
16
|
-
"src/functions/*.ts"
|
|
17
|
-
]
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowJs": true,
|
|
4
|
+
"skipLibCheck": true,
|
|
5
|
+
"strict": false,
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"rootDir": ".",
|
|
9
|
+
"sourceMap": true,
|
|
10
|
+
"module": "CommonJS",
|
|
11
|
+
"target": "ES6",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": false,
|
|
14
|
+
},
|
|
15
|
+
"include": [
|
|
16
|
+
"src/functions/*.ts"
|
|
17
|
+
]
|
|
18
18
|
}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "seeka-app-example-name",
|
|
3
|
-
"version": "2.0.7-rc.2",
|
|
4
|
-
"private": true,
|
|
5
|
-
"workspaces": [
|
|
6
|
-
"app/*"
|
|
7
|
-
],
|
|
8
|
-
"scripts": {
|
|
9
|
-
"clean": "yarn workspaces foreach --all -pt run clean",
|
|
10
|
-
"lint": "yarn workspaces foreach --all -pt run lint",
|
|
11
|
-
"build:azure-function": "yarn workspace @seeka-app-example-name/browser run build && yarn workspace @seeka-app-example-name/server-azure-function run build",
|
|
12
|
-
"dev:azure-function": "yarn clean && yarn workspace @seeka-app-example-name/browser run build:dev && yarn workspace @seeka-app-example-name/server-azure-function run build && yarn workspace @seeka-app-example-name/server-azure-function run dev",
|
|
13
|
-
"deploy:azure-function": "yarn workspace @seeka-app-example-name/server-azure-function run deploy",
|
|
14
|
-
"tunnel:azure-function": "yarn workspace @seeka-app-example-name/server-azure-function run tunnel",
|
|
15
|
-
"bump:patch": "yarn git:isclean && yarn workspaces foreach --all version patch --deferred && yarn bump:apply && yarn git:push",
|
|
16
|
-
"bump:minor": "yarn git:isclean && yarn workspaces foreach --all version minor --deferred && yarn bump:apply && yarn git:push",
|
|
17
|
-
"bump:major": "yarn git:isclean && yarn workspaces foreach --all version major --deferred && yarn bump:apply && yarn git:push",
|
|
18
|
-
"bump:alpha": "yarn git:isclean && yarn workspaces foreach --all version prerelease --deferred && yarn bump:apply && yarn git:push",
|
|
19
|
-
"bump:apply": "yarn version apply --all",
|
|
20
|
-
"git:isclean": "bash -c 'if [ -n \"$(git status --porcelain)\" ]; then echo \"✖ Working directory not clean. Commit or stash your changes first.\"; exit 1; fi'",
|
|
21
|
-
"git:push": "git add -A && git commit -m \"v$(node -p \"require('./package.json').version\")\" && git tag -a v$(node -p \"require('./package.json').version\") -m \"v$(node -p \"require('./package.json').version\")\""
|
|
22
|
-
},
|
|
23
|
-
"devDependencies": {
|
|
24
|
-
"azure-functions-core-tools": "^4.x"
|
|
25
|
-
},
|
|
26
|
-
"packageManager": "yarn@4.9.1",
|
|
27
|
-
"stableVersion": "2.0.6"
|
|
28
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "seeka-app-example-name",
|
|
3
|
+
"version": "2.0.7-rc.2",
|
|
4
|
+
"private": true,
|
|
5
|
+
"workspaces": [
|
|
6
|
+
"app/*"
|
|
7
|
+
],
|
|
8
|
+
"scripts": {
|
|
9
|
+
"clean": "yarn workspaces foreach --all -pt run clean",
|
|
10
|
+
"lint": "yarn workspaces foreach --all -pt run lint",
|
|
11
|
+
"build:azure-function": "yarn workspace @seeka-app-example-name/browser run build && yarn workspace @seeka-app-example-name/server-azure-function run build",
|
|
12
|
+
"dev:azure-function": "yarn clean && yarn workspace @seeka-app-example-name/browser run build:dev && yarn workspace @seeka-app-example-name/server-azure-function run build && yarn workspace @seeka-app-example-name/server-azure-function run dev",
|
|
13
|
+
"deploy:azure-function": "yarn workspace @seeka-app-example-name/server-azure-function run deploy",
|
|
14
|
+
"tunnel:azure-function": "yarn workspace @seeka-app-example-name/server-azure-function run tunnel",
|
|
15
|
+
"bump:patch": "yarn git:isclean && yarn workspaces foreach --all version patch --deferred && yarn bump:apply && yarn git:push",
|
|
16
|
+
"bump:minor": "yarn git:isclean && yarn workspaces foreach --all version minor --deferred && yarn bump:apply && yarn git:push",
|
|
17
|
+
"bump:major": "yarn git:isclean && yarn workspaces foreach --all version major --deferred && yarn bump:apply && yarn git:push",
|
|
18
|
+
"bump:alpha": "yarn git:isclean && yarn workspaces foreach --all version prerelease --deferred && yarn bump:apply && yarn git:push",
|
|
19
|
+
"bump:apply": "yarn version apply --all",
|
|
20
|
+
"git:isclean": "bash -c 'if [ -n \"$(git status --porcelain)\" ]; then echo \"✖ Working directory not clean. Commit or stash your changes first.\"; exit 1; fi'",
|
|
21
|
+
"git:push": "git add -A && git commit -m \"v$(node -p \"require('./package.json').version\")\" && git tag -a v$(node -p \"require('./package.json').version\") -m \"v$(node -p \"require('./package.json').version\")\""
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"azure-functions-core-tools": "^4.x"
|
|
25
|
+
},
|
|
26
|
+
"packageManager": "yarn@4.9.1",
|
|
27
|
+
"stableVersion": "2.0.6"
|
|
28
|
+
}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"allowJs": true,
|
|
4
|
-
"skipLibCheck": true,
|
|
5
|
-
"strict": false,
|
|
6
|
-
"esModuleInterop": true,
|
|
7
|
-
"sourceMap": true,
|
|
8
|
-
"module": "CommonJS",
|
|
9
|
-
"target": "ES6",
|
|
10
|
-
"resolveJsonModule": true,
|
|
11
|
-
"isolatedModules": false,
|
|
12
|
-
"baseUrl": ".",
|
|
13
|
-
"paths": {
|
|
14
|
-
"@seeka-app-example-name/*": ["app/*/src"]
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"references": [
|
|
18
|
-
{ "path": "app/server-azure-function" },
|
|
19
|
-
{ "path": "app/browser" }
|
|
20
|
-
],
|
|
21
|
-
"exclude": [
|
|
22
|
-
"node_modules",
|
|
23
|
-
"**/dist"
|
|
24
|
-
]
|
|
25
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowJs": true,
|
|
4
|
+
"skipLibCheck": true,
|
|
5
|
+
"strict": false,
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"sourceMap": true,
|
|
8
|
+
"module": "CommonJS",
|
|
9
|
+
"target": "ES6",
|
|
10
|
+
"resolveJsonModule": true,
|
|
11
|
+
"isolatedModules": false,
|
|
12
|
+
"baseUrl": ".",
|
|
13
|
+
"paths": {
|
|
14
|
+
"@seeka-app-example-name/*": ["app/*/src"]
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"references": [
|
|
18
|
+
{ "path": "app/server-azure-function" },
|
|
19
|
+
{ "path": "app/browser" }
|
|
20
|
+
],
|
|
21
|
+
"exclude": [
|
|
22
|
+
"node_modules",
|
|
23
|
+
"**/dist"
|
|
24
|
+
]
|
|
25
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seeka-labs/cli-apps",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.10-alpha.0",
|
|
4
4
|
"description": "Seeka - Apps CLI",
|
|
5
5
|
"author": "SEEKA <platform@seeka.co>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"ts-jest": "^29.3.4",
|
|
45
45
|
"typescript": "^5.8.3"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "a189a826d921d74c9c4c2f5b71ebc8b0b8cf4652",
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"lodash-es": "^4.17.21",
|
|
50
50
|
"source-map-support": "^0.5.21"
|