@rsdk/cli 4.2.5-next.0 → 4.3.0-next.1
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/CHANGELOG.md +12 -0
- package/README.MD +15 -0
- package/TODO.MD +5 -0
- package/bin.js +10 -0
- package/dist/exception.d.ts +4 -0
- package/dist/exception.js +23 -0
- package/dist/exception.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/package.loader.d.ts +6 -0
- package/dist/package.loader.js +28 -0
- package/dist/package.loader.js.map +1 -0
- package/dist/reconfigure-logger.d.ts +5 -0
- package/dist/reconfigure-logger.js +12 -0
- package/dist/reconfigure-logger.js.map +1 -0
- package/package.json +11 -6
- package/src/exception.ts +25 -0
- package/src/index.ts +73 -0
- package/src/package.loader.ts +36 -0
- package/src/reconfigure-logger.ts +13 -0
- package/dist/bin.d.ts +0 -2
- package/dist/bin.js +0 -21
- package/dist/bin.js.map +0 -1
- package/dist/kafka/commands/extract/extract.command.d.ts +0 -2
- package/dist/kafka/commands/extract/extract.command.js +0 -17
- package/dist/kafka/commands/extract/extract.command.js.map +0 -1
- package/dist/kafka/commands/extract/kafka-config.extractor.d.ts +0 -6
- package/dist/kafka/commands/extract/kafka-config.extractor.js +0 -40
- package/dist/kafka/commands/extract/kafka-config.extractor.js.map +0 -1
- package/dist/kafka/commands/extract/types.d.ts +0 -85
- package/dist/kafka/commands/extract/types.js +0 -3
- package/dist/kafka/commands/extract/types.js.map +0 -1
- package/dist/kafka/commands/schema/print-schema.d.ts +0 -5
- package/dist/kafka/commands/schema/print-schema.js +0 -11
- package/dist/kafka/commands/schema/print-schema.js.map +0 -1
- package/dist/kafka/commands/schema/schema.command.d.ts +0 -2
- package/dist/kafka/commands/schema/schema.command.js +0 -12
- package/dist/kafka/commands/schema/schema.command.js.map +0 -1
- package/dist/kafka/commands/sync/check-exist.d.ts +0 -7
- package/dist/kafka/commands/sync/check-exist.js +0 -57
- package/dist/kafka/commands/sync/check-exist.js.map +0 -1
- package/dist/kafka/commands/sync/context.d.ts +0 -3
- package/dist/kafka/commands/sync/context.js +0 -3
- package/dist/kafka/commands/sync/context.js.map +0 -1
- package/dist/kafka/commands/sync/create-topic.task.d.ts +0 -5
- package/dist/kafka/commands/sync/create-topic.task.js +0 -28
- package/dist/kafka/commands/sync/create-topic.task.js.map +0 -1
- package/dist/kafka/commands/sync/get-config.d.ts +0 -5
- package/dist/kafka/commands/sync/get-config.js +0 -28
- package/dist/kafka/commands/sync/get-config.js.map +0 -1
- package/dist/kafka/commands/sync/kafka.creds-provider.d.ts +0 -4
- package/dist/kafka/commands/sync/kafka.creds-provider.js +0 -22
- package/dist/kafka/commands/sync/kafka.creds-provider.js.map +0 -1
- package/dist/kafka/commands/sync/sync.command.d.ts +0 -2
- package/dist/kafka/commands/sync/sync.command.js +0 -49
- package/dist/kafka/commands/sync/sync.command.js.map +0 -1
- package/dist/kafka/config.schema.d.ts +0 -34
- package/dist/kafka/config.schema.js +0 -26
- package/dist/kafka/config.schema.js.map +0 -1
- package/dist/kafka/schemas/string-enum.d.ts +0 -2
- package/dist/kafka/schemas/string-enum.js +0 -14
- package/dist/kafka/schemas/string-enum.js.map +0 -1
- package/src/bin.ts +0 -26
- package/src/kafka/commands/extract/extract.command.ts +0 -16
- package/src/kafka/commands/extract/kafka-config.extractor.ts +0 -47
- package/src/kafka/commands/extract/types.ts +0 -101
- package/src/kafka/commands/schema/print-schema.ts +0 -15
- package/src/kafka/commands/schema/schema.command.ts +0 -10
- package/src/kafka/commands/sync/check-exist.ts +0 -68
- package/src/kafka/commands/sync/context.ts +0 -3
- package/src/kafka/commands/sync/create-topic.task.ts +0 -35
- package/src/kafka/commands/sync/get-config.ts +0 -25
- package/src/kafka/commands/sync/kafka.creds-provider.ts +0 -16
- package/src/kafka/commands/sync/sync.command.ts +0 -66
- package/src/kafka/config.schema.ts +0 -31
- package/src/kafka/schemas/string-enum.ts +0 -15
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { InternalException } from '@rsdk/core';
|
|
2
|
-
import type { Static } from '@sinclair/typebox';
|
|
3
|
-
import type { Admin } from 'kafkajs';
|
|
4
|
-
import { ConfigResourceTypes } from 'kafkajs';
|
|
5
|
-
import type { Listr, ListrRendererFactory, ListrTaskWrapper } from 'listr2';
|
|
6
|
-
import { delay } from 'listr2';
|
|
7
|
-
|
|
8
|
-
import type { TopicSchema } from '../../config.schema';
|
|
9
|
-
|
|
10
|
-
export class KafkaTopicConfigurator {
|
|
11
|
-
static async configure(
|
|
12
|
-
topic: Static<typeof TopicSchema>,
|
|
13
|
-
admin: Admin,
|
|
14
|
-
parentTask: ListrTaskWrapper<unknown, ListrRendererFactory>,
|
|
15
|
-
): Promise<Listr | void> {
|
|
16
|
-
const metadata = await admin.fetchTopicMetadata({
|
|
17
|
-
topics: [topic.name],
|
|
18
|
-
});
|
|
19
|
-
const partitions = metadata.topics[0].partitions.length;
|
|
20
|
-
if (topic.spec?.partitions && partitions !== topic.spec.partitions) {
|
|
21
|
-
throw new Error(
|
|
22
|
-
`partitoins for ${topic.name} settled to ${partitions}, but expected ${topic.spec.partitions}`,
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
const topicConfig = await admin.describeConfigs({
|
|
26
|
-
resources: [
|
|
27
|
-
{
|
|
28
|
-
type: ConfigResourceTypes.TOPIC,
|
|
29
|
-
configNames: ['cleanup.policy'],
|
|
30
|
-
name: topic.name,
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
includeSynonyms: true,
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const cleanupPolicy = topicConfig.resources.find(
|
|
37
|
-
({ resourceName }) => resourceName === topic.name,
|
|
38
|
-
);
|
|
39
|
-
if (!cleanupPolicy) {
|
|
40
|
-
throw new InternalException('cleanupPolicy not found');
|
|
41
|
-
}
|
|
42
|
-
const currentValue = cleanupPolicy?.configEntries[0].configValue;
|
|
43
|
-
const configValue = topic?.spec?.settings?.['cleanup.policy'];
|
|
44
|
-
|
|
45
|
-
if (configValue && currentValue !== configValue) {
|
|
46
|
-
parentTask.output = `Alter cleanup.policy from ${currentValue} to ${configValue}`;
|
|
47
|
-
await delay(3e3);
|
|
48
|
-
await admin.alterConfigs({
|
|
49
|
-
validateOnly: false,
|
|
50
|
-
resources: [
|
|
51
|
-
{
|
|
52
|
-
type: ConfigResourceTypes.TOPIC,
|
|
53
|
-
configEntries: [
|
|
54
|
-
{
|
|
55
|
-
value: configValue,
|
|
56
|
-
name: 'cleanup.policy',
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
name: topic.name,
|
|
60
|
-
},
|
|
61
|
-
],
|
|
62
|
-
});
|
|
63
|
-
parentTask.output = `Alter cleanup.policy from ${currentValue} to ${configValue} completed!`;
|
|
64
|
-
await delay(3e3);
|
|
65
|
-
}
|
|
66
|
-
parentTask.title = `topic ${topic.name} exists and respond config`;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { Static } from '@sinclair/typebox';
|
|
2
|
-
import type { Admin } from 'kafkajs';
|
|
3
|
-
import type { ListrRendererFactory, ListrTaskWrapper } from 'listr2';
|
|
4
|
-
import { delay } from 'listr2';
|
|
5
|
-
|
|
6
|
-
import type { TopicSchema } from '../../config.schema';
|
|
7
|
-
|
|
8
|
-
export async function createTopic(
|
|
9
|
-
topic: Static<typeof TopicSchema>,
|
|
10
|
-
admin: Admin,
|
|
11
|
-
parentTask: ListrTaskWrapper<unknown, ListrRendererFactory>,
|
|
12
|
-
): Promise<void> {
|
|
13
|
-
await delay(1000);
|
|
14
|
-
const numPartitions = topic.spec?.partitions ?? 2;
|
|
15
|
-
|
|
16
|
-
const replicationFactor = topic.spec?.replicationFactor;
|
|
17
|
-
|
|
18
|
-
const result = await admin.createTopics({
|
|
19
|
-
topics: [
|
|
20
|
-
{
|
|
21
|
-
topic: topic.name,
|
|
22
|
-
...(replicationFactor && {
|
|
23
|
-
replicationFactor: replicationFactor,
|
|
24
|
-
}),
|
|
25
|
-
numPartitions: numPartitions,
|
|
26
|
-
},
|
|
27
|
-
],
|
|
28
|
-
});
|
|
29
|
-
if (result) {
|
|
30
|
-
console.log('create topic %s complete!', topic.name);
|
|
31
|
-
parentTask.title = `create topic ${topic.name} complete!`;
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
throw new Error(`create topic ${topic.name} failed!`);
|
|
35
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { InputException } from '@rsdk/core';
|
|
2
|
-
import type { Static } from '@sinclair/typebox';
|
|
3
|
-
import { readFile } from 'node:fs/promises';
|
|
4
|
-
import { resolve } from 'node:path';
|
|
5
|
-
import yaml from 'yaml';
|
|
6
|
-
|
|
7
|
-
import type { CliKafkaConfigSchema } from '../../config.schema';
|
|
8
|
-
import { CliKafkaConfigSchemaChecker } from '../../config.schema';
|
|
9
|
-
|
|
10
|
-
export class KafkaExpectedConfigProvider {
|
|
11
|
-
static async getConfig(): Promise<Static<typeof CliKafkaConfigSchema>> {
|
|
12
|
-
const kafkaYml = await readFile(resolve('kafka.yml'), {
|
|
13
|
-
encoding: 'utf8',
|
|
14
|
-
});
|
|
15
|
-
const config: Static<typeof CliKafkaConfigSchema> = yaml.parse(kafkaYml);
|
|
16
|
-
|
|
17
|
-
const isValid = CliKafkaConfigSchemaChecker.Check(config);
|
|
18
|
-
if (!isValid) {
|
|
19
|
-
throw new InputException('Invalid config', {
|
|
20
|
-
cause: [...CliKafkaConfigSchemaChecker.Errors(config)],
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
return config;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { InternalException } from '@rsdk/core';
|
|
2
|
-
import dotenv from 'dotenv';
|
|
3
|
-
import type { KafkaConfig } from 'kafkajs';
|
|
4
|
-
|
|
5
|
-
export class KafkaCredsProvider {
|
|
6
|
-
static getKafkaCreds(): KafkaConfig {
|
|
7
|
-
dotenv.config();
|
|
8
|
-
const kafkaHost = process.env.KAFKA_HOST;
|
|
9
|
-
if (!kafkaHost) {
|
|
10
|
-
throw new InternalException('KAFKA_HOST not found');
|
|
11
|
-
}
|
|
12
|
-
return {
|
|
13
|
-
brokers: [kafkaHost],
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import type { Admin, KafkaConfig } from 'kafkajs';
|
|
3
|
-
import { Kafka } from 'kafkajs';
|
|
4
|
-
import { Listr } from 'listr2';
|
|
5
|
-
|
|
6
|
-
import { KafkaConfigExtractor } from '../extract/kafka-config.extractor';
|
|
7
|
-
|
|
8
|
-
import { KafkaTopicConfigurator } from './check-exist';
|
|
9
|
-
import type { Context } from './context';
|
|
10
|
-
import { createTopic } from './create-topic.task';
|
|
11
|
-
import { KafkaExpectedConfigProvider } from './get-config';
|
|
12
|
-
import { KafkaCredsProvider } from './kafka.creds-provider';
|
|
13
|
-
|
|
14
|
-
async function createAdmin(kafkaCreds: KafkaConfig): Promise<Admin> {
|
|
15
|
-
const kafka = new Kafka(kafkaCreds);
|
|
16
|
-
const admin = kafka.admin();
|
|
17
|
-
|
|
18
|
-
await admin.connect();
|
|
19
|
-
return admin;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const KafkaSyncCommand = new Command('sync')
|
|
23
|
-
.description('try sync kafka state from kafka.yml file')
|
|
24
|
-
.option('--from-rsdk', 'run command based on rsdk.json, instead of kafka.yml')
|
|
25
|
-
.action(async function (_, command: Command) {
|
|
26
|
-
const options = command.opts();
|
|
27
|
-
const config = options.fromRsdk
|
|
28
|
-
? await KafkaConfigExtractor.extract()
|
|
29
|
-
: await KafkaExpectedConfigProvider.getConfig();
|
|
30
|
-
|
|
31
|
-
const kafkaCreds = KafkaCredsProvider.getKafkaCreds();
|
|
32
|
-
const admin = await createAdmin(kafkaCreds);
|
|
33
|
-
|
|
34
|
-
const existedTopic = await admin.listTopics();
|
|
35
|
-
|
|
36
|
-
await new Listr<Context>(
|
|
37
|
-
config.topics.map((topic) => ({
|
|
38
|
-
title: topic.name,
|
|
39
|
-
task: async (_ctx, parentTask): Promise<boolean | Listr> => {
|
|
40
|
-
const requireCreate = !existedTopic.includes(topic.name);
|
|
41
|
-
|
|
42
|
-
return parentTask.newListr(
|
|
43
|
-
[
|
|
44
|
-
{
|
|
45
|
-
title: requireCreate ? 'create' : 'configure',
|
|
46
|
-
task: async (): Promise<void | Listr> => {
|
|
47
|
-
if (requireCreate) {
|
|
48
|
-
await createTopic(topic, admin, parentTask);
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
await KafkaTopicConfigurator.configure(
|
|
52
|
-
topic,
|
|
53
|
-
admin,
|
|
54
|
-
parentTask,
|
|
55
|
-
);
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
{ concurrent: false },
|
|
60
|
-
);
|
|
61
|
-
},
|
|
62
|
-
})),
|
|
63
|
-
{ concurrent: true },
|
|
64
|
-
).run({ requireCreate: true });
|
|
65
|
-
await admin.disconnect();
|
|
66
|
-
});
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Type } from '@sinclair/typebox';
|
|
2
|
-
import { TypeCompiler } from '@sinclair/typebox/compiler';
|
|
3
|
-
|
|
4
|
-
import { StringEnum } from './schemas/string-enum';
|
|
5
|
-
|
|
6
|
-
const specSchema = Type.Optional(
|
|
7
|
-
Type.Partial(
|
|
8
|
-
Type.Object({
|
|
9
|
-
partitions: Type.Integer({
|
|
10
|
-
default: 2,
|
|
11
|
-
}),
|
|
12
|
-
replicationFactor: Type.Integer({
|
|
13
|
-
default: 1,
|
|
14
|
-
}),
|
|
15
|
-
settings: Type.Object({
|
|
16
|
-
'cleanup.policy': StringEnum(['delete', 'compact']),
|
|
17
|
-
}),
|
|
18
|
-
}),
|
|
19
|
-
),
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
export const TopicSchema = Type.Object({
|
|
23
|
-
name: Type.String(),
|
|
24
|
-
spec: Type.Optional(specSchema),
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
export const CliKafkaConfigSchema = Type.Object({
|
|
28
|
-
topics: Type.Array(TopicSchema),
|
|
29
|
-
});
|
|
30
|
-
export const CliKafkaConfigSchemaChecker =
|
|
31
|
-
TypeCompiler.Compile(CliKafkaConfigSchema);
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { TUnsafe } from '@sinclair/typebox';
|
|
2
|
-
import { Kind, Type, TypeRegistry } from '@sinclair/typebox';
|
|
3
|
-
|
|
4
|
-
TypeRegistry.Set('StringEnum', (schema: any, value: any) => {
|
|
5
|
-
return schema.enum.includes(value);
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
export const StringEnum = <T extends string[]>(
|
|
9
|
-
values: [...T],
|
|
10
|
-
): TUnsafe<T[number]> =>
|
|
11
|
-
Type.Unsafe<T[number]>({
|
|
12
|
-
[Kind]: 'StringEnum',
|
|
13
|
-
type: 'string',
|
|
14
|
-
enum: values,
|
|
15
|
-
});
|