@seeka-labs/cli-apps 1.1.39 → 2.0.7-rc.2
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/index.js +31 -36
- package/dist/index.js.map +4 -4
- package/dist/init-template/.gitlab-ci.yml +47 -0
- package/dist/init-template/.yarnrc.yml +8 -0
- package/dist/init-template/README.md +7 -0
- package/dist/{init-templates → init-template/app}/browser/jest.config.js +11 -11
- package/dist/{init-templates → init-template/app}/browser/package.json +16 -12
- package/dist/{init-templates → init-template/app}/browser/scripts/esbuild/build-browser-plugin.mjs +110 -110
- package/dist/{init-templates → init-template/app}/browser/scripts/esbuild/plugins/importAsGlobals.mjs +38 -38
- package/dist/{init-templates → init-template/app}/browser/src/browser.ts +12 -12
- package/dist/{init-templates → init-template/app}/browser/src/plugin/index.test.ts +6 -6
- package/dist/{init-templates → init-template/app}/browser/src/plugin/index.ts +47 -49
- package/dist/{init-templates → init-template/app}/browser/tsconfig.json +34 -34
- package/dist/{init-templates/netlify-function → init-template/app/server-azure-function}/.eslintrc.cjs +2 -10
- package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/.funcignore +12 -7
- package/dist/init-template/app/server-azure-function/.nvmrc +1 -0
- package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/README.md +104 -107
- package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/host.json +1 -10
- package/dist/init-template/app/server-azure-function/package.json +52 -0
- package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/src/functions/seekaAppWebhook.ts +235 -236
- package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/src/lib/browser/index.ts +54 -54
- package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/src/lib/jobs/index.ts +1 -1
- package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/src/lib/logging/index.ts +92 -92
- package/dist/{init-templates/azure-function/src/lib/browser → init-template/app/server-azure-function/src/lib}/models/index.ts +6 -6
- package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/src/lib/state/redis/index.ts +96 -65
- package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/src/lib/state/seeka/installations.ts +64 -66
- package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/tsconfig.json +1 -1
- package/dist/init-template/package.json +28 -0
- package/dist/init-template/tsconfig.json +25 -0
- package/package.json +5 -4
- package/dist/init-templates/aws-lambda/.env.example +0 -15
- package/dist/init-templates/aws-lambda/.eslintrc.cjs +0 -19
- package/dist/init-templates/aws-lambda/.example.gitignore +0 -49
- package/dist/init-templates/aws-lambda/.gitlab-ci.yml +0 -39
- package/dist/init-templates/aws-lambda/.nvmrc +0 -1
- package/dist/init-templates/aws-lambda/.vscode/extensions.json +0 -5
- package/dist/init-templates/aws-lambda/.vscode/launch.json +0 -20
- package/dist/init-templates/aws-lambda/.vscode/settings.json +0 -3
- package/dist/init-templates/aws-lambda/.vscode/tasks.json +0 -12
- package/dist/init-templates/aws-lambda/README.md +0 -77
- package/dist/init-templates/aws-lambda/jest.config.js +0 -5
- package/dist/init-templates/aws-lambda/package.json +0 -53
- package/dist/init-templates/aws-lambda/scripts/ngrok.js +0 -28
- package/dist/init-templates/aws-lambda/src/index.test.ts +0 -7
- package/dist/init-templates/aws-lambda/src/index.ts +0 -33
- package/dist/init-templates/aws-lambda/src/lib/logging/index.ts +0 -88
- package/dist/init-templates/aws-lambda/src/lib/services/index.ts +0 -41
- package/dist/init-templates/aws-lambda/src/lib/state/redis/index.ts +0 -65
- package/dist/init-templates/aws-lambda/src/lib/state/seeka/installations.ts +0 -67
- package/dist/init-templates/aws-lambda/src/routes/seekaAppWebhook.ts +0 -194
- package/dist/init-templates/aws-lambda/tsconfig.json +0 -31
- package/dist/init-templates/aws-lambda/yarn.lock +0 -4392
- package/dist/init-templates/azure-function/.eslintrc.cjs +0 -19
- package/dist/init-templates/azure-function/.example.gitignore +0 -48
- package/dist/init-templates/azure-function/.gitlab-ci.yml +0 -48
- package/dist/init-templates/azure-function/.nvmrc +0 -1
- package/dist/init-templates/azure-function/.vscode/extensions.json +0 -7
- package/dist/init-templates/azure-function/.vscode/launch.json +0 -13
- package/dist/init-templates/azure-function/.vscode/settings.json +0 -9
- package/dist/init-templates/azure-function/.vscode/tasks.json +0 -39
- package/dist/init-templates/azure-function/jest.config.js +0 -5
- package/dist/init-templates/azure-function/package.json +0 -47
- package/dist/init-templates/azure-function/scripts/dev-queue-setup.js +0 -30
- package/dist/init-templates/azure-function/src/index.test.ts +0 -7
- package/dist/init-templates/azure-function/yarn.lock +0 -3772
- package/dist/init-templates/browser/.editorconfig +0 -14
- package/dist/init-templates/browser/.eslintrc.cjs +0 -1
- package/dist/init-templates/browser/.yarnrc +0 -1
- package/dist/init-templates/browser/yarn.lock +0 -3045
- package/dist/init-templates/netlify-function/.env.example +0 -18
- package/dist/init-templates/netlify-function/.example.gitignore +0 -36
- package/dist/init-templates/netlify-function/.nvmrc +0 -1
- package/dist/init-templates/netlify-function/.vscode/launch.json +0 -45
- package/dist/init-templates/netlify-function/README.md +0 -62
- package/dist/init-templates/netlify-function/jest.config.js +0 -5
- package/dist/init-templates/netlify-function/netlify.toml +0 -7
- package/dist/init-templates/netlify-function/package.json +0 -39
- package/dist/init-templates/netlify-function/src/api/example-job-background/index.ts +0 -52
- package/dist/init-templates/netlify-function/src/api/polling-example-job-scheduled/index.ts +0 -46
- package/dist/init-templates/netlify-function/src/api/seeka-app-webhook/index.ts +0 -217
- package/dist/init-templates/netlify-function/src/index.test.ts +0 -7
- package/dist/init-templates/netlify-function/src/lib/jobs/index.ts +0 -68
- package/dist/init-templates/netlify-function/src/lib/logging/index.ts +0 -91
- package/dist/init-templates/netlify-function/src/lib/services/index.ts +0 -41
- package/dist/init-templates/netlify-function/src/lib/state/redis/index.ts +0 -65
- package/dist/init-templates/netlify-function/src/lib/state/seeka/installations.ts +0 -67
- package/dist/init-templates/netlify-function/tsconfig.json +0 -25
- package/dist/init-templates/netlify-function/yarn.lock +0 -9337
- /package/dist/{init-templates → init-template/app}/browser/README.md +0 -0
- /package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/local.settings.example.json +0 -0
- /package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/scripts/ngrok.js +0 -0
- /package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/src/functions/healthCheck.ts +0 -0
- /package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/src/functions/pollingExample.ts +0 -0
- /package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/src/functions/queueExample.ts +0 -0
- /package/dist/{init-templates/azure-function → init-template/app/server-azure-function}/src/lib/services/index.ts +0 -0
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
import * as winston from 'winston';
|
|
2
|
-
|
|
3
|
-
import { InvocationContext } from '@azure/functions';
|
|
4
|
-
import { SeqTransport } from '@datalust/winston-seq';
|
|
5
|
-
|
|
6
|
-
import * as packageJson from '../../../package.json';
|
|
7
|
-
import { BackgroundJobRequestContext } from '../jobs';
|
|
8
|
-
|
|
9
|
-
import type {
|
|
10
|
-
SeekaWebhookPayload, SeekaWebhookPayloadOfSeekaAppWebhookContext
|
|
11
|
-
} from '@seeka-labs/sdk-apps-server';
|
|
12
|
-
|
|
13
|
-
const loggerTransports: winston.transport[] = [
|
|
14
|
-
new winston.transports.Console({
|
|
15
|
-
level: process.env.LOGGING_LEVEL,
|
|
16
|
-
format: winston.format.combine(
|
|
17
|
-
winston.format.errors({ stack: true }),
|
|
18
|
-
winston.format.cli(),
|
|
19
|
-
winston.format.splat(),
|
|
20
|
-
),
|
|
21
|
-
handleExceptions: true,
|
|
22
|
-
handleRejections: true,
|
|
23
|
-
}),
|
|
24
|
-
]
|
|
25
|
-
if (process.env.LOGGING_SEQ_SERVERURL) {
|
|
26
|
-
loggerTransports.push(
|
|
27
|
-
new SeqTransport({
|
|
28
|
-
level: process.env.LOGGING_LEVEL,
|
|
29
|
-
serverUrl: process.env.LOGGING_SEQ_SERVERURL,
|
|
30
|
-
apiKey: process.env.LOGGING_SEQ_APIKEY,
|
|
31
|
-
onError: ((e) => { console.error('Failed to configure Seq logging transport', e) }),
|
|
32
|
-
format: winston.format.combine(
|
|
33
|
-
winston.format.errors({ stack: true }),
|
|
34
|
-
winston.format.json(),
|
|
35
|
-
),
|
|
36
|
-
handleExceptions: true,
|
|
37
|
-
handleRejections: true,
|
|
38
|
-
})
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export const logger = winston.createLogger({
|
|
43
|
-
level: process.env.LOGGING_LEVEL,
|
|
44
|
-
defaultMeta: {
|
|
45
|
-
seekaAppId: process.env.SEEKA_APP_ID,
|
|
46
|
-
Hosting_Provider: 'azure',
|
|
47
|
-
Release_Version: `v${packageJson.version}`,
|
|
48
|
-
Hosting_Region: process.env.REGION_NAME,
|
|
49
|
-
Service_Instance_Id: process.env.WEBSITE_ROLE_INSTANCE_ID,
|
|
50
|
-
AzureFunctions_FunctionName: process.env.WEBSITE_SITE_NAME,
|
|
51
|
-
Service: `app/${packageJson.name}`,
|
|
52
|
-
},
|
|
53
|
-
transports: loggerTransports,
|
|
54
|
-
exitOnError: false,
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
export const childLogger = (meta: object) => logger.child(meta);
|
|
58
|
-
|
|
59
|
-
export const webhookLogger = (payload: SeekaWebhookPayload, functionContext: InvocationContext) => {
|
|
60
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
|
-
const meta: any = {
|
|
62
|
-
seekaWebhookType: payload.type,
|
|
63
|
-
seekaWebhookIsTest: payload.isTest,
|
|
64
|
-
RequestId: payload.requestId,
|
|
65
|
-
AzureFunctions_InvocationId: functionContext.invocationId,
|
|
66
|
-
CausationId: payload.causationId,
|
|
67
|
-
CorrelationId: payload.causationId,
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const context = (payload as SeekaWebhookPayloadOfSeekaAppWebhookContext).context;
|
|
71
|
-
if (context) {
|
|
72
|
-
meta.seekaAppInstallId = context.applicationInstallId;
|
|
73
|
-
meta.seekaAppInstallOrganisationBrandId = context.organisationBrandId;
|
|
74
|
-
meta.seekaAppInstallOrganisationId = context.organisationId;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return childLogger(meta)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export const backgroundJobLogger = (jobName: string, jobContext: BackgroundJobRequestContext | undefined, functionContext: InvocationContext) => {
|
|
81
|
-
const meta: object = {
|
|
82
|
-
jobContext,
|
|
83
|
-
jobName,
|
|
84
|
-
AzureFunctions_InvocationId: functionContext.invocationId,
|
|
85
|
-
CausationId: jobContext?.causationId,
|
|
86
|
-
CorrelationId: jobContext?.causationId,
|
|
87
|
-
seekaAppInstallId: jobContext?.applicationInstallId,
|
|
88
|
-
seekaAppInstallOrganisationBrandId: jobContext?.organisationBrandId,
|
|
89
|
-
seekaAppInstallOrganisationId: jobContext?.organisationId
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return childLogger(meta)
|
|
1
|
+
import * as winston from 'winston';
|
|
2
|
+
|
|
3
|
+
import { InvocationContext } from '@azure/functions';
|
|
4
|
+
import { SeqTransport } from '@datalust/winston-seq';
|
|
5
|
+
|
|
6
|
+
import * as packageJson from '../../../package.json';
|
|
7
|
+
import { BackgroundJobRequestContext } from '../jobs';
|
|
8
|
+
|
|
9
|
+
import type {
|
|
10
|
+
SeekaWebhookPayload, SeekaWebhookPayloadOfSeekaAppWebhookContext
|
|
11
|
+
} from '@seeka-labs/sdk-apps-server';
|
|
12
|
+
|
|
13
|
+
const loggerTransports: winston.transport[] = [
|
|
14
|
+
new winston.transports.Console({
|
|
15
|
+
level: process.env.LOGGING_LEVEL,
|
|
16
|
+
format: winston.format.combine(
|
|
17
|
+
winston.format.errors({ stack: true }),
|
|
18
|
+
winston.format.cli(),
|
|
19
|
+
winston.format.splat(),
|
|
20
|
+
),
|
|
21
|
+
handleExceptions: true,
|
|
22
|
+
handleRejections: true,
|
|
23
|
+
}),
|
|
24
|
+
]
|
|
25
|
+
if (process.env.LOGGING_SEQ_SERVERURL) {
|
|
26
|
+
loggerTransports.push(
|
|
27
|
+
new SeqTransport({
|
|
28
|
+
level: process.env.LOGGING_LEVEL,
|
|
29
|
+
serverUrl: process.env.LOGGING_SEQ_SERVERURL,
|
|
30
|
+
apiKey: process.env.LOGGING_SEQ_APIKEY,
|
|
31
|
+
onError: ((e) => { console.error('Failed to configure Seq logging transport', e) }),
|
|
32
|
+
format: winston.format.combine(
|
|
33
|
+
winston.format.errors({ stack: true }),
|
|
34
|
+
winston.format.json(),
|
|
35
|
+
),
|
|
36
|
+
handleExceptions: true,
|
|
37
|
+
handleRejections: true,
|
|
38
|
+
})
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const logger = winston.createLogger({
|
|
43
|
+
level: process.env.LOGGING_LEVEL,
|
|
44
|
+
defaultMeta: {
|
|
45
|
+
seekaAppId: process.env.SEEKA_APP_ID,
|
|
46
|
+
Hosting_Provider: 'azure',
|
|
47
|
+
Release_Version: `v${packageJson.version}`,
|
|
48
|
+
Hosting_Region: process.env.REGION_NAME,
|
|
49
|
+
Service_Instance_Id: process.env.WEBSITE_ROLE_INSTANCE_ID,
|
|
50
|
+
AzureFunctions_FunctionName: process.env.WEBSITE_SITE_NAME,
|
|
51
|
+
Service: `app/${packageJson.name}`,
|
|
52
|
+
},
|
|
53
|
+
transports: loggerTransports,
|
|
54
|
+
exitOnError: false,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export const childLogger = (meta: object) => logger.child(meta);
|
|
58
|
+
|
|
59
|
+
export const webhookLogger = (payload: SeekaWebhookPayload, functionContext: InvocationContext) => {
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
|
+
const meta: any = {
|
|
62
|
+
seekaWebhookType: payload.type,
|
|
63
|
+
seekaWebhookIsTest: payload.isTest,
|
|
64
|
+
RequestId: payload.requestId,
|
|
65
|
+
AzureFunctions_InvocationId: functionContext.invocationId,
|
|
66
|
+
CausationId: payload.causationId,
|
|
67
|
+
CorrelationId: payload.causationId,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const context = (payload as SeekaWebhookPayloadOfSeekaAppWebhookContext).context;
|
|
71
|
+
if (context) {
|
|
72
|
+
meta.seekaAppInstallId = context.applicationInstallId;
|
|
73
|
+
meta.seekaAppInstallOrganisationBrandId = context.organisationBrandId;
|
|
74
|
+
meta.seekaAppInstallOrganisationId = context.organisationId;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return childLogger(meta)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const backgroundJobLogger = (jobName: string, jobContext: BackgroundJobRequestContext | undefined, functionContext: InvocationContext) => {
|
|
81
|
+
const meta: object = {
|
|
82
|
+
jobContext,
|
|
83
|
+
jobName,
|
|
84
|
+
AzureFunctions_InvocationId: functionContext.invocationId,
|
|
85
|
+
CausationId: jobContext?.causationId,
|
|
86
|
+
CorrelationId: jobContext?.causationId,
|
|
87
|
+
seekaAppInstallId: jobContext?.applicationInstallId,
|
|
88
|
+
seekaAppInstallOrganisationBrandId: jobContext?.organisationBrandId,
|
|
89
|
+
seekaAppInstallOrganisationId: jobContext?.organisationId
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return childLogger(meta)
|
|
93
93
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export interface ISampleAppBrowserSdkPluginConfig {
|
|
2
|
-
myAppInstallSetting1: string | number | undefined;
|
|
3
|
-
myAppInstallSetting2: string | number | undefined;
|
|
4
|
-
appId: string
|
|
5
|
-
appInstallId: string
|
|
6
|
-
appUrl: string
|
|
1
|
+
export interface ISampleAppBrowserSdkPluginConfig {
|
|
2
|
+
myAppInstallSetting1: string | number | undefined;
|
|
3
|
+
myAppInstallSetting2: string | number | undefined;
|
|
4
|
+
appId: string
|
|
5
|
+
appInstallId: string
|
|
6
|
+
appUrl: string
|
|
7
7
|
}
|
|
@@ -1,65 +1,96 @@
|
|
|
1
|
-
import { createClient } from 'redis';
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
const redisProtocol = process.env.REDIS_CONNECTION_TLS === 'true' ? 'rediss://' : 'redis://';
|
|
7
|
-
const redisConn = `${redisProtocol}${process.env.REDIS_CONNECTION_USER}:${process.env.REDIS_CONNECTION_PASSWORD}@${process.env.REDIS_CONNECTION_HOST}:${process.env.REDIS_CONNECTION_PORT}`;
|
|
8
|
-
|
|
9
|
-
const redisClient = createClient({
|
|
10
|
-
url: redisConn
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
await redisClient.
|
|
65
|
-
|
|
1
|
+
import { createClient } from 'redis';
|
|
2
|
+
|
|
3
|
+
import winston from 'winston';
|
|
4
|
+
import { logger } from '../../logging';
|
|
5
|
+
|
|
6
|
+
const redisProtocol = process.env.REDIS_CONNECTION_TLS === 'true' ? 'rediss://' : 'redis://';
|
|
7
|
+
const redisConn = `${redisProtocol}${process.env.REDIS_CONNECTION_USER}:${process.env.REDIS_CONNECTION_PASSWORD}@${process.env.REDIS_CONNECTION_HOST}:${process.env.REDIS_CONNECTION_PORT}`;
|
|
8
|
+
|
|
9
|
+
const redisClient = createClient({
|
|
10
|
+
url: redisConn,
|
|
11
|
+
disableClientInfo: true,
|
|
12
|
+
|
|
13
|
+
})
|
|
14
|
+
.on('error', (err) => logger.error('Redis Client ', { ex: winston.exceptions.getAllInfo(err) }));
|
|
15
|
+
|
|
16
|
+
export const connect = async () => {
|
|
17
|
+
await redisClient.connect();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const isConnected = () => {
|
|
21
|
+
return redisClient.isOpen;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const disconnect = async () => {
|
|
25
|
+
await redisClient.destroy();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const getKeyPrefix = (stateType: string) => `seeka:app:${process.env.SEEKA_APP_ID}:${stateType}`
|
|
29
|
+
const getKey = (stateType: string, key: string) => `${getKeyPrefix(stateType)}:${key}`
|
|
30
|
+
|
|
31
|
+
export async function getOrCreate<TState>(stateType: string, key: string, toCreate: TState, mode: 'string' | 'json' = 'string'): Promise<TState> {
|
|
32
|
+
const fullKey = getKey(stateType, key);
|
|
33
|
+
const existingStr = await getString(redisClient, fullKey);
|
|
34
|
+
if (existingStr) return JSON.parse(existingStr);
|
|
35
|
+
|
|
36
|
+
if (mode === 'json') {
|
|
37
|
+
await redisClient.json.set(fullKey, '$', toCreate as never);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
await redisClient.set(fullKey, JSON.stringify(toCreate));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return toCreate;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export async function tryGet<TState>(stateType: string, key: string, mode: 'string' | 'json' = 'string'): Promise<TState | null> {
|
|
47
|
+
const fullKey = getKey(stateType, key);
|
|
48
|
+
|
|
49
|
+
if (mode === 'json') {
|
|
50
|
+
const existing = await redisClient.json.get(fullKey);
|
|
51
|
+
if (existing) return existing as TState;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
const existingStr = await getString(redisClient, fullKey);
|
|
55
|
+
if (existingStr) return JSON.parse(existingStr);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export async function getList<TState>(stateType: string): Promise<TState[]> {
|
|
62
|
+
const prefix = getKeyPrefix(stateType);
|
|
63
|
+
const allKeys = await redisClient.keys(`${prefix}:*`);
|
|
64
|
+
const listStr = await redisClient.mGet(allKeys);
|
|
65
|
+
|
|
66
|
+
if (listStr) return listStr.filter(e => Boolean(e)).map(e => JSON.parse(e as string));
|
|
67
|
+
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function set<TState>(stateType: string, key: string, toCreate: TState, mode: 'string' | 'json' = 'string'): Promise<void> {
|
|
72
|
+
const fullKey = getKey(stateType, key);
|
|
73
|
+
|
|
74
|
+
if (mode === 'json') {
|
|
75
|
+
await redisClient.json.set(fullKey, '$', toCreate as never);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
await redisClient.set(fullKey, JSON.stringify(toCreate));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export async function remove(stateType: string, key: string): Promise<void> {
|
|
83
|
+
const fullKey = getKey(stateType, key);
|
|
84
|
+
await redisClient.del(fullKey);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function getString(redisClient: any, key: string): Promise<string> {
|
|
88
|
+
const result = await redisClient.get(key);
|
|
89
|
+
if (typeof result === 'string') {
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
if (result) {
|
|
93
|
+
return result.toString();
|
|
94
|
+
}
|
|
95
|
+
return '';
|
|
96
|
+
}
|
|
@@ -1,67 +1,65 @@
|
|
|
1
|
-
import type { Logger } from 'winston';
|
|
2
|
-
|
|
3
|
-
import { getList, remove, set, tryGet } from '../redis';
|
|
4
|
-
|
|
5
|
-
export interface SeekaAppInstallState {
|
|
6
|
-
/** ID of the organisation that installed the app */
|
|
7
|
-
organisationId: string;
|
|
8
|
-
/** ID of the brand that installed the app */
|
|
9
|
-
organisationBrandId: string;
|
|
10
|
-
/** ID of the installation of the app */
|
|
11
|
-
applicationInstallId: string;
|
|
12
|
-
// Installation settings provided by the user installing the app
|
|
13
|
-
installationSettings: SampleAppInstallSettings
|
|
14
|
-
// State relating to the app and installation of the app
|
|
15
|
-
installationState: SampleAppInstallState;
|
|
16
|
-
|
|
17
|
-
// When the app was installed
|
|
18
|
-
installedAt: string; // new Date().toISOString()
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface SampleAppInstallState {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
logger.info('Deleted installation state', { applicationInstallId });
|
|
1
|
+
import type { Logger } from 'winston';
|
|
2
|
+
|
|
3
|
+
import { getList, remove, set, tryGet } from '../redis';
|
|
4
|
+
|
|
5
|
+
export interface SeekaAppInstallState {
|
|
6
|
+
/** ID of the organisation that installed the app */
|
|
7
|
+
organisationId: string;
|
|
8
|
+
/** ID of the brand that installed the app */
|
|
9
|
+
organisationBrandId: string;
|
|
10
|
+
/** ID of the installation of the app */
|
|
11
|
+
applicationInstallId: string;
|
|
12
|
+
// Installation settings provided by the user installing the app
|
|
13
|
+
installationSettings: SampleAppInstallSettings
|
|
14
|
+
// State relating to the app and installation of the app
|
|
15
|
+
installationState: SampleAppInstallState;
|
|
16
|
+
|
|
17
|
+
// When the app was installed
|
|
18
|
+
installedAt: string; // new Date().toISOString()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface SampleAppInstallState {
|
|
22
|
+
grantedPermissions?: string[]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type SampleAppInstallSettings = { [key: string]: any; } | {
|
|
26
|
+
myAppInstallSetting1: string | number | undefined;
|
|
27
|
+
myAppInstallSetting2: string | number | undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const stateType = 'install'
|
|
31
|
+
|
|
32
|
+
export const tryGetInstallation = async (applicationInstallId: string, throwWhenNotFound: boolean, logger: Logger): Promise<SeekaAppInstallState | null> => {
|
|
33
|
+
const installation = await tryGet<SeekaAppInstallState>(stateType, applicationInstallId);
|
|
34
|
+
if (installation == null && throwWhenNotFound) {
|
|
35
|
+
throw new Error(`Seeka installation ${applicationInstallId} not found`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return installation;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const listInstallations = async (logger: Logger): Promise<SeekaAppInstallState[]> => {
|
|
42
|
+
const installations = await getList<SeekaAppInstallState>(stateType);
|
|
43
|
+
|
|
44
|
+
return installations;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
export const createOrUpdateInstallation = async (state: SeekaAppInstallState, logger: Logger): Promise<SeekaAppInstallState> => {
|
|
49
|
+
if (!state.installationState) state.installationState = {};
|
|
50
|
+
if (!state.installedAt) state.installedAt = new Date().toISOString();
|
|
51
|
+
|
|
52
|
+
const creating = (await tryGetInstallation(state.applicationInstallId, false, logger)) === null;
|
|
53
|
+
|
|
54
|
+
await set(stateType, state.applicationInstallId, state);
|
|
55
|
+
|
|
56
|
+
logger.info(creating ? 'Created installation state' : 'Updated installation state', { applicationInstallId: state.applicationInstallId, organisationId: state.organisationId, organisationBrandId: state.organisationBrandId });
|
|
57
|
+
|
|
58
|
+
return state;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const deleteInstallation = async (applicationInstallId: string, logger: Logger): Promise<void> => {
|
|
62
|
+
await remove(stateType, applicationInstallId);
|
|
63
|
+
|
|
64
|
+
logger.info('Deleted installation state', { applicationInstallId });
|
|
67
65
|
}
|
|
@@ -0,0 +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
|
+
}
|
|
@@ -0,0 +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
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seeka-labs/cli-apps",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.7-rc.2",
|
|
4
4
|
"description": "Seeka - Apps CLI",
|
|
5
5
|
"author": "SEEKA <platform@seeka.co>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,14 +39,15 @@
|
|
|
39
39
|
"camelcase": "^8.0.0",
|
|
40
40
|
"commander": "^14.0.0",
|
|
41
41
|
"cross-spawn": "^7.0.6",
|
|
42
|
-
"esbuild": "^0.25.
|
|
42
|
+
"esbuild": "^0.25.5",
|
|
43
43
|
"jest": "^29.7.0",
|
|
44
44
|
"ts-jest": "^29.3.4",
|
|
45
45
|
"typescript": "^5.8.3"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "3090cdc0329c28d427d15343ac3b2b486b5d5627",
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"lodash-es": "^4.17.21",
|
|
50
50
|
"source-map-support": "^0.5.21"
|
|
51
|
-
}
|
|
51
|
+
},
|
|
52
|
+
"stableVersion": "2.0.6"
|
|
52
53
|
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
SEEKA_APP_ID=
|
|
2
|
-
SEEKA_APP_SECRET=
|
|
3
|
-
SEEKA_DEBUG_ENABLED=true
|
|
4
|
-
SEEKA_INGEST_URL=
|
|
5
|
-
SEEKA_ISSUER_URL=
|
|
6
|
-
NODE_TLS_REJECT_UNAUTHORIZED=1
|
|
7
|
-
REDIS_CONNECTION_USER=default
|
|
8
|
-
REDIS_CONNECTION_PASSWORD=
|
|
9
|
-
REDIS_CONNECTION_TLS=true
|
|
10
|
-
REDIS_CONNECTION_HOST=
|
|
11
|
-
REDIS_CONNECTION_PORT=
|
|
12
|
-
LOGGING_SEQ_SERVERURL=
|
|
13
|
-
LOGGING_SEQ_APIKEY=
|
|
14
|
-
LOGGING_LEVEL=silly
|
|
15
|
-
NODE_OPTIONS=--enable-source-maps
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/* eslint-env node */
|
|
2
|
-
module.exports = {
|
|
3
|
-
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
|
|
4
|
-
parser: '@typescript-eslint/parser',
|
|
5
|
-
plugins: ['@typescript-eslint'],
|
|
6
|
-
root: true,
|
|
7
|
-
rules: {
|
|
8
|
-
"@typescript-eslint/no-unused-vars": "warn",
|
|
9
|
-
"@typescript-eslint/no-explicit-any": "off"
|
|
10
|
-
},
|
|
11
|
-
overrides: [
|
|
12
|
-
{
|
|
13
|
-
files: ["**/*/*.test.ts"],
|
|
14
|
-
env: {
|
|
15
|
-
jest: true
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
]
|
|
19
|
-
};
|