jitsu-cli 0.7.2 → 0.9.0-alpha.169

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.
@@ -2,23 +2,45 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.build = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const path_1 = (0, tslib_1.__importDefault)(require("path"));
6
- const log_1 = (0, tslib_1.__importDefault)(require("../../lib/log"));
7
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
8
- const fs_1 = (0, tslib_1.__importDefault)(require("fs"));
5
+ const path_1 = tslib_1.__importDefault(require("path"));
6
+ const log_1 = tslib_1.__importDefault(require("../../lib/log"));
7
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
+ const fs_1 = tslib_1.__importDefault(require("fs"));
9
9
  const errors_1 = require("../../lib/errors");
10
10
  const rollup_1 = require("rollup");
11
- const rollup_plugin_typescript2_1 = (0, tslib_1.__importDefault)(require("rollup-plugin-typescript2"));
12
- const plugin_multi_entry_1 = (0, tslib_1.__importDefault)(require("@rollup/plugin-multi-entry"));
13
- const plugin_node_resolve_1 = (0, tslib_1.__importDefault)(require("@rollup/plugin-node-resolve"));
14
- const plugin_commonjs_1 = (0, tslib_1.__importDefault)(require("@rollup/plugin-commonjs"));
11
+ const rollup_plugin_typescript2_1 = tslib_1.__importDefault(require("rollup-plugin-typescript2"));
12
+ const plugin_multi_entry_1 = tslib_1.__importDefault(require("@rollup/plugin-multi-entry"));
13
+ const plugin_json_1 = tslib_1.__importDefault(require("@rollup/plugin-json"));
14
+ const plugin_node_resolve_1 = tslib_1.__importDefault(require("@rollup/plugin-node-resolve"));
15
+ const plugin_commonjs_1 = tslib_1.__importDefault(require("@rollup/plugin-commonjs"));
15
16
  const version_1 = require("../../lib/version");
16
17
  const _1 = require("./");
17
- const JSON5_1 = (0, tslib_1.__importDefault)(require("JSON5"));
18
+ const JSON5 = tslib_1.__importStar(require("json5"));
19
+ function fixNodeFetch(code) {
20
+ return code.replace("throw new TypeError('Expected signal to be an instanceof AbortSignal');", "");
21
+ }
22
+ function insertStreamReaderFacade(targetFile) {
23
+ return {
24
+ name: "insert-stream-reader-facade",
25
+ transform: async (code, id) => {
26
+ const [path] = id.split("?");
27
+ if (path === targetFile) {
28
+ let newCode = [
29
+ `import * as srcLib from "@jitsu/jlib/lib/sources-lib";`,
30
+ code,
31
+ ";",
32
+ `export const __$srcLib = srcLib;`,
33
+ ].join("\n");
34
+ return { code: newCode };
35
+ }
36
+ return null;
37
+ },
38
+ };
39
+ }
18
40
  async function build(args) {
19
41
  const directory = args?.[0] || "";
20
42
  let projectBase = path_1.default.isAbsolute(directory) ? directory : path_1.default.resolve(process.cwd() + "/" + directory);
21
- (0, log_1.default)().info("🔨 Building project in " + chalk_1.default.bold(projectBase));
43
+ (0, log_1.default)().info("🔨 Building project in " + chalk_1.default.bold(projectBase) + ` with ${version_1.jitsuPackageName}@${version_1.jitsuCliVersion} `);
22
44
  if (!fs_1.default.existsSync(projectBase)) {
23
45
  throw new Error(`Path ${projectBase} does not exist`);
24
46
  }
@@ -28,7 +50,7 @@ async function build(args) {
28
50
  }
29
51
  let packageJson;
30
52
  try {
31
- packageJson = JSON5_1.default.parse(fs_1.default.readFileSync(packageFile, "utf8"));
53
+ packageJson = JSON5.parse(fs_1.default.readFileSync(packageFile, "utf8"));
32
54
  }
33
55
  catch (e) {
34
56
  throw new Error((0, errors_1.appendError)(`Failed to parse package.json at ${projectBase}`, e));
@@ -48,7 +70,7 @@ async function build(args) {
48
70
  };
49
71
  }
50
72
  (0, _1.validateTsConfig)(tsConfigPath);
51
- (0, log_1.default)().info("Building project");
73
+ (0, log_1.default)().info("Building project...");
52
74
  try {
53
75
  let indexFile = path_1.default.resolve(projectBase, "src/index.ts");
54
76
  if (!fs_1.default.existsSync(indexFile)) {
@@ -56,21 +78,36 @@ async function build(args) {
56
78
  }
57
79
  const bundle = await (0, rollup_1.rollup)({
58
80
  input: [indexFile],
59
- plugins: [typescriptEnabled && (0, rollup_plugin_typescript2_1.default)({ cwd: projectBase }), (0, plugin_multi_entry_1.default)(), (0, plugin_node_resolve_1.default)(), (0, plugin_commonjs_1.default)()],
81
+ plugins: [
82
+ typescriptEnabled && (0, rollup_plugin_typescript2_1.default)({ cwd: projectBase }),
83
+ insertStreamReaderFacade(indexFile),
84
+ (0, plugin_multi_entry_1.default)(),
85
+ (0, plugin_node_resolve_1.default)({ preferBuiltins: false }),
86
+ (0, plugin_commonjs_1.default)(),
87
+ (0, plugin_json_1.default)(),
88
+ ],
60
89
  });
61
- (0, log_1.default)().info("Generating bundle");
90
+ let format = "cjs";
62
91
  let output = await bundle.generate({
63
- generatedCode: "es2015",
64
- format: "cjs",
92
+ generatedCode: "es5",
93
+ format: format,
94
+ exports: "named",
95
+ banner: `//format=${format}`,
96
+ outro: [
97
+ `exports.buildInfo = {sdkVersion: "${version_1.jitsuCliVersion}", sdkPackage: "${version_1.jitsuPackageName}", buildTimestamp: "${new Date().toISOString()}"};`,
98
+ `exports.streamReader$StdoutFacade = exports.streamReader && __$srcLib.stdoutStreamReader(exports.streamReader);`,
99
+ ].join("\n"),
65
100
  });
101
+ let code = fixNodeFetch(output.output[0].code);
102
+ fs_1.default.mkdirSync(path_1.default.dirname(fullOutputPath), { recursive: true });
103
+ fs_1.default.writeFileSync(fullOutputPath, code);
66
104
  (0, log_1.default)().info("Validating build");
67
- let code = output.output[0].code;
68
- code += `\nexports.buildInfo = {sdkVersion: "${version_1.jitsuCliVersion}", sdkPackage: "${version_1.jitsuPackageName}", buildTimestamp: "${new Date().toISOString()}"}`;
69
- const exports = (0, _1.loadBuild)(code);
70
- if (!exports.destination && !exports.transform) {
105
+ const exports = await (0, _1.loadBuild)(fullOutputPath);
106
+ if (!exports.destination && !exports.transform && !(exports.streamReader && exports.sourceCatalog)) {
71
107
  return {
72
108
  success: false,
73
- message: `${chalk_1.default.bold(indexFile)} should export ${chalk_1.default.italic("destination")} or ${chalk_1.default.italic("transform")} symbol. It exports: ` + Object.keys(exports).join(", "),
109
+ message: `${chalk_1.default.bold(indexFile)} should export ${chalk_1.default.italic("destination")}, ${chalk_1.default.italic("transform")} or both ${chalk_1.default.italic("streamReader")} and ${chalk_1.default.italic("sourceCatalog")} symbols. It exports: ` +
110
+ Object.keys(exports).join(", "),
74
111
  };
75
112
  }
76
113
  else if (exports.destination && exports.transform) {
@@ -79,8 +116,6 @@ async function build(args) {
79
116
  message: `${chalk_1.default.bold(indexFile)} exports both ${chalk_1.default.italic("destination")} and ${chalk_1.default.italic("transform")} symbol. It should export either of them` + Object.keys(exports).join(", "),
80
117
  };
81
118
  }
82
- fs_1.default.mkdirSync(path_1.default.dirname(fullOutputPath), { recursive: true });
83
- fs_1.default.writeFileSync(fullOutputPath, code);
84
119
  }
85
120
  catch (e) {
86
121
  if (e.id && e.loc && e.frame) {
@@ -2,18 +2,18 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.create = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const commander_1 = (0, tslib_1.__importDefault)(require("commander"));
6
- const validate_npm_package_name_1 = (0, tslib_1.__importDefault)(require("validate-npm-package-name"));
7
- const inquirer_1 = (0, tslib_1.__importDefault)(require("inquirer"));
8
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
9
- const path_1 = (0, tslib_1.__importDefault)(require("path"));
10
- const fs_1 = (0, tslib_1.__importDefault)(require("fs"));
11
- const log_1 = (0, tslib_1.__importDefault)(require("../../lib/log"));
5
+ const commander_1 = tslib_1.__importDefault(require("commander"));
6
+ const validate_npm_package_name_1 = tslib_1.__importDefault(require("validate-npm-package-name"));
7
+ const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
8
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
9
+ const path_1 = tslib_1.__importDefault(require("path"));
10
+ const fs_1 = tslib_1.__importDefault(require("fs"));
11
+ const log_1 = tslib_1.__importDefault(require("../../lib/log"));
12
12
  const template_1 = require("../../lib/template");
13
13
  const template_2 = require("./template");
14
14
  async function create(args) {
15
15
  const program = new commander_1.default.Command();
16
- program.option("-t, --type <project type>", "project type (destination or transform)");
16
+ program.option("-t, --type <project type>", "project type (destination or source)");
17
17
  program.option("-d, --dir <project_dir>", "project dir");
18
18
  program.option("-n, --name <project_name>", "project name");
19
19
  program.option("-j, --jitsu-version <jitsu_version>", "Jitsu version");
@@ -33,9 +33,9 @@ async function create(args) {
33
33
  message: [
34
34
  `What is the type of extension?`,
35
35
  ` ${chalk_1.default.bold("destination")} adds a new type of HTTP-based destination to Jitsu`,
36
- ` ${chalk_1.default.bold("transform")} adds a transformation logic`,
36
+ ` ${chalk_1.default.bold("source")} adds a new source extension to Jitsu`,
37
37
  ].join("\n"),
38
- choices: ["destination", "transform"],
38
+ choices: ["destination", "source"],
39
39
  },
40
40
  ])).package;
41
41
  let packageName = cliOpts.name ||
@@ -1,2 +1,3 @@
1
1
  import { CommandResult } from "../../lib/command/types";
2
- export declare function execExtension(args: string[]): Promise<CommandResult>;
2
+ export declare function execSourceExtension(args: string[]): Promise<CommandResult>;
3
+ export declare function execDestinationExtension(args: string[]): Promise<CommandResult>;
@@ -1,27 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.execExtension = void 0;
3
+ exports.execDestinationExtension = exports.execSourceExtension = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const commander_1 = (0, tslib_1.__importDefault)(require("commander"));
6
- const log_1 = (0, tslib_1.__importDefault)(require("../../lib/log"));
7
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
8
- const path_1 = (0, tslib_1.__importDefault)(require("path"));
9
- const JSON5_1 = (0, tslib_1.__importDefault)(require("JSON5"));
10
- const fs_1 = (0, tslib_1.__importDefault)(require("fs"));
5
+ const commander_1 = tslib_1.__importDefault(require("commander"));
6
+ const log_1 = tslib_1.__importDefault(require("../../lib/log"));
7
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
+ const path_1 = tslib_1.__importDefault(require("path"));
9
+ const JSON5 = tslib_1.__importStar(require("json5"));
10
+ const fs_1 = tslib_1.__importDefault(require("fs"));
11
11
  const index_1 = require("./index");
12
12
  const indent_1 = require("../../lib/indent");
13
13
  const chalk_code_highlight_1 = require("../../lib/chalk-code-highlight");
14
- const validator_helper_1 = require("../../lib/validator-helper");
15
14
  const errors_1 = require("../../lib/errors");
15
+ const validation_1 = require("../../lib/validation");
16
+ const build_1 = require("./build");
17
+ const sources_lib_1 = require("@jitsu/jlib/lib/sources-lib");
16
18
  function getJson(json, file) {
17
19
  if (json) {
18
- return JSON5_1.default.parse(json);
20
+ return JSON5.parse(json);
19
21
  }
20
22
  else {
21
23
  if (!fs_1.default.existsSync(file)) {
22
24
  throw new Error(`File ${file} does not exist!`);
23
25
  }
24
- return JSON5_1.default.parse(fs_1.default.readFileSync(file, "utf-8"));
26
+ return JSON5.parse(fs_1.default.readFileSync(file, "utf-8"));
25
27
  }
26
28
  }
27
29
  function ellipsis(str, opts = { maxLen: 80 }) {
@@ -36,52 +38,219 @@ function toArray(obj) {
36
38
  return obj;
37
39
  }
38
40
  }
39
- async function execExtension(args) {
41
+ async function loadExtension(directory) {
42
+ let projectBase = path_1.default.isAbsolute(directory) ? directory : path_1.default.resolve(process.cwd() + "/" + directory);
43
+ let packageFile = path_1.default.resolve(projectBase, "package.json");
44
+ if (!fs_1.default.existsSync(packageFile)) {
45
+ throw new Error("Can't find package.json in " + projectBase);
46
+ }
47
+ let distFile = path_1.default.resolve(projectBase, (0, index_1.getDistFile)(JSON5.parse(fs_1.default.readFileSync(packageFile, "utf-8"))));
48
+ (0, log_1.default)().info("⌛️ Loading extension (don't forget to build it before running exec!). Source: " + chalk_1.default.bold(distFile));
49
+ if (!fs_1.default.existsSync(path_1.default.resolve(projectBase, distFile))) {
50
+ throw new Error(`Can't find dist file ${chalk_1.default.bold(distFile)}. Does this dir contains jitsu extension? Have you run yarn build? `);
51
+ }
52
+ let extension = await (0, index_1.loadBuild)(distFile);
53
+ return { extension, distFile, projectBase };
54
+ }
55
+ async function execSourceExtension(args) {
56
+ const program = new commander_1.default.Command();
57
+ program.option("-c, --config <config_file_or_json>", "Configuration file path or inline extension configuration JSON");
58
+ program.option("-d, --dir <project_dir>", "project dir");
59
+ program.option("-s, --stream-config <json>", "Stream configuration as an object.");
60
+ program.option("-t, --state <file>", "Saved state object to file");
61
+ program.parse(["dummy", "dummy", ...args]);
62
+ let cliOpts = program.opts();
63
+ let directory = cliOpts.dir || ".";
64
+ await (0, build_1.build)([directory]);
65
+ const { extension } = await loadExtension(directory);
66
+ if (!extension.streamReader) {
67
+ return { success: false, message: `Extension doesn't export ${chalk_1.default.bold("streamReader")} symbol` };
68
+ }
69
+ if (!extension.sourceCatalog) {
70
+ return { success: false, message: `Extension doesn't export ${chalk_1.default.bold("sourceCatalog")} symbol` };
71
+ }
72
+ let configObject;
73
+ try {
74
+ configObject = (0, index_1.getConfigJson)(cliOpts.config);
75
+ }
76
+ catch (e) {
77
+ return {
78
+ success: false,
79
+ message: `Can't parse config JSON: '${cliOpts.config}' ${e.message})`,
80
+ };
81
+ }
82
+ const stateFile = path_1.default.resolve(cliOpts.state || `./src-${extension?.descriptor?.id || ""}-state.json`);
83
+ const stateFilePresent = fs_1.default.existsSync(stateFile);
84
+ if (stateFilePresent) {
85
+ (0, log_1.default)().info(`Loading state from ${chalk_1.default.bold(path_1.default.isAbsolute(stateFile))}`);
86
+ }
87
+ else {
88
+ (0, log_1.default)().info(`State file is missing, starting with empty state ${chalk_1.default.bold(stateFile)}`);
89
+ }
90
+ const stateObject = stateFilePresent ? JSON5.parse(fs_1.default.readFileSync(stateFile, "utf-8")) : {};
91
+ if (!extension.validator) {
92
+ (0, log_1.default)().info("⚠️ Extension doesn't support connection validation");
93
+ }
94
+ else {
95
+ (0, log_1.default)().info("⌛️ Validating connection parameters...");
96
+ let validationError = await (0, validation_1.validateConfiguration)(configObject, extension.validator);
97
+ if (validationError) {
98
+ return {
99
+ success: false,
100
+ message: `Configuration validation failed: ${validationError}`,
101
+ };
102
+ }
103
+ (0, log_1.default)().info("🙌️ Configuration is valid!");
104
+ }
105
+ (0, log_1.default)().info("🏃 Getting available streams...");
106
+ let streams = await extension.sourceCatalog(configObject);
107
+ streams.forEach(stream => {
108
+ let paramsDocs = (stream.params ?? []).map(param => `${param.id} - ${param.displayName}`).join(", ");
109
+ (0, log_1.default)().info(`🌊 Stream: ${chalk_1.default.bold(stream.type)}. Parameters: ${paramsDocs.length > 0 ? paramsDocs : "none"}`);
110
+ });
111
+ let stream;
112
+ let streamConfigObject = cliOpts.streamConfig && JSON5.parse(cliOpts.streamConfig);
113
+ let mode = streamConfigObject?.mode;
114
+ if (streams.length > 1) {
115
+ if (!streamConfigObject) {
116
+ return {
117
+ success: false,
118
+ message: `The connector exports more than one (${streams.length}) streams. Please specify stream name and config as -s {stream: 'name', ...}`,
119
+ };
120
+ }
121
+ if (!streamConfigObject?.name) {
122
+ return {
123
+ success: false,
124
+ message: `Connector defines multiple streams (${streams.map(s => s.type)}). Specify stream name as as: -s {name: 'name', ...}`,
125
+ };
126
+ }
127
+ stream = streams.find(stream => stream.type === streamConfigObject?.name);
128
+ if (!stream) {
129
+ return { success: false, message: `Stream with ${streamConfigObject?.name} is not found` };
130
+ }
131
+ }
132
+ else {
133
+ stream = streams[0];
134
+ }
135
+ const modes = stream.supportedModes;
136
+ if (!mode && modes.length > 1) {
137
+ return {
138
+ success: false,
139
+ message: `Stream ${stream.type} supports multiple modes (${modes.join(", ")}). Please specify mode as -s {mode: '${modes[0]}', ...}`,
140
+ };
141
+ }
142
+ if (mode && !modes.includes(mode)) {
143
+ return {
144
+ success: false,
145
+ message: `Stream ${stream.type} doesn't support mode ${mode}. Supported modes: ${modes.join(", ")}`,
146
+ };
147
+ }
148
+ const effectiveMode = mode || modes[0];
149
+ const resultTable = newTable();
150
+ const sink = (0, sources_lib_1.makeStreamSink)({
151
+ msg(msg) {
152
+ if (msg.type === "record") {
153
+ (0, log_1.default)().info("[" + msg.type + "] " + (msg.message ? JSON.stringify(msg.message) : ""));
154
+ add(resultTable, msg.message);
155
+ }
156
+ else if (msg.type === "log") {
157
+ (0, log_1.default)()[msg.message?.["level"].toLowerCase()]?.("[" + msg.type + "] " + msg.message?.["message"]);
158
+ }
159
+ else if (msg.type === "state") {
160
+ (0, log_1.default)().info("[" + msg.type + "] " + (msg.message ? JSON.stringify(msg.message) : ""));
161
+ (0, log_1.default)().info(`💾 State was modified. Saving to: ${chalk_1.default.bold(path_1.default.isAbsolute(stateFile))}`);
162
+ fs_1.default.writeFileSync(stateFile, JSON.stringify(msg.message, null, 2));
163
+ }
164
+ else {
165
+ (0, log_1.default)().info("[" + msg.type + "] " + (msg.message ? JSON.stringify(msg.message) : ""));
166
+ }
167
+ },
168
+ }, effectiveMode);
169
+ let streamConfiguration = { parameters: streamConfigObject };
170
+ if (mode) {
171
+ streamConfiguration.mode = mode;
172
+ }
173
+ await extension.streamReader(configObject, stream.type, streamConfiguration, sink, {
174
+ state: (0, sources_lib_1.stateService)(stateObject, sink),
175
+ });
176
+ (0, log_1.default)().info("🏁 Result data:");
177
+ console.log(JSON.stringify(resultTable.rows, null, 2));
178
+ console.log("Special column types: \n" +
179
+ Object.entries(resultTable.columns)
180
+ .filter(([colName, colValue]) => colValue.types.length > 0)
181
+ .map(([colName, colValue]) => `\t${colName}: ${colValue.types}`)
182
+ .join("\n"));
183
+ return { success: true };
184
+ }
185
+ exports.execSourceExtension = execSourceExtension;
186
+ function newTable() {
187
+ return { rows: [], columns: {} };
188
+ }
189
+ function add(t, rec) {
190
+ const newRow = {};
191
+ for (const [key, val] of Object.entries(rec)) {
192
+ if (key.indexOf("__sql_type") !== 0) {
193
+ if (t.columns[key] === undefined) {
194
+ t.columns[key] = { types: [] };
195
+ t.rows.forEach(row => (row[key] = undefined));
196
+ }
197
+ newRow[key] = Array.isArray(val) ? JSON.stringify(val) : val;
198
+ }
199
+ else {
200
+ const columnName = key.substring("__sql_type_".length);
201
+ if (t.columns[columnName] === undefined) {
202
+ t.columns[columnName] = { types: [] };
203
+ }
204
+ let uniqueTypes = new Set(t.columns[columnName].types);
205
+ uniqueTypes.add(val);
206
+ t.columns[columnName].types = [...uniqueTypes];
207
+ }
208
+ }
209
+ Object.keys(t.columns).forEach(col => {
210
+ if (newRow[col] === undefined) {
211
+ newRow[col] = undefined;
212
+ }
213
+ });
214
+ t.rows.push(newRow);
215
+ }
216
+ async function execDestinationExtension(args) {
40
217
  const program = new commander_1.default.Command();
41
218
  program.option("-f, --file <file path>", "Path to file with jitsu events. Could be either on object, or array of objects");
42
- program.option("-c, --config <file path>", "Path to file with config ");
43
- program.option("-o, --config-object <file path>", "Config json");
219
+ program.option("-c, --config <config_file_or_json>", "Configuration file path or inline extension configuration JSON");
44
220
  program.option("-j, --json <event json>", "Events JSON for processing (alternative to -f). Could be one object, or array of objects");
45
221
  program.option("-d, --dir <project_dir>", "project dir");
46
222
  program.option("-v, --skip-validation", "To skip config validation");
47
223
  program.parse(["dummy", "dummy", ...args]);
48
224
  let cliOpts = program.opts();
49
225
  let directory = cliOpts.dir || ".";
50
- let projectBase = path_1.default.isAbsolute(directory) ? directory : path_1.default.resolve(process.cwd() + "/" + directory);
51
- let packageFile = path_1.default.resolve(projectBase, "package.json");
52
- if (!fs_1.default.existsSync(packageFile)) {
53
- return { success: false, message: "Can't find package.json in " + projectBase };
54
- }
55
226
  if (!cliOpts.json && !cliOpts.file) {
56
227
  return { success: false, message: "Please specify -j or -f" };
57
228
  }
58
229
  if (cliOpts.json && cliOpts.file) {
59
230
  return { success: false, message: "Both options -f and -j are provided. You should use either, not both" };
60
231
  }
61
- if (cliOpts.config && cliOpts.configObject) {
62
- return { success: false, message: "Both options -o and -c are provided. You should use either, not both" };
232
+ if (!cliOpts.config) {
233
+ return { success: false, message: "Please define config object -c json_file_path or -c '{json_object:}'" };
63
234
  }
64
- if (!cliOpts.config && !cliOpts.configObject) {
65
- return { success: false, message: "Please specify -o or -c" };
235
+ let config;
236
+ try {
237
+ config = (0, index_1.getConfigJson)(cliOpts.config);
66
238
  }
67
- (0, log_1.default)().info("🛂 Executing tests destination on " + chalk_1.default.bold(projectBase));
68
- let events = toArray(getJson(cliOpts.json, cliOpts.file));
69
- let config = getJson(cliOpts.configObject, cliOpts.config);
70
- let distFile = path_1.default.resolve(projectBase, (0, index_1.getDistFile)(JSON5_1.default.parse(fs_1.default.readFileSync(packageFile, "utf-8"))));
71
- (0, log_1.default)().info("⌛️ Loading destination plugin (don't forget to build it before running exec!). Source: " + chalk_1.default.bold(distFile));
72
- if (!fs_1.default.existsSync(path_1.default.resolve(projectBase, distFile))) {
239
+ catch (e) {
73
240
  return {
74
241
  success: false,
75
- message: `Can't find dist file ${chalk_1.default.bold(distFile)}. Does this dir contains jitsu extension? Have you run yarn build? `,
242
+ message: `Can't parse config JSON: '${cliOpts.config}' ${e.message})`,
76
243
  };
77
244
  }
78
- let extension = (0, index_1.loadBuild)(fs_1.default.readFileSync(distFile, "utf-8"));
245
+ const { extension, projectBase } = await loadExtension(directory);
246
+ (0, log_1.default)().info("🛂 Executing tests destination on " + chalk_1.default.bold(projectBase));
247
+ let events = toArray(getJson(cliOpts.json, cliOpts.file));
79
248
  if (!extension.destination) {
80
249
  return { success: false, message: "Extension doesn't export destination function" };
81
250
  }
82
251
  if (!cliOpts.skipValidation && extension.validator) {
83
252
  (0, log_1.default)().info(`Validating configuration:${chalk_code_highlight_1.chalkCode.json((0, indent_1.align)(JSON.stringify(config, null, 2), { indent: 4, lnBefore: 1, lnAfter: 1 }))}`);
84
- let configError = await (0, validator_helper_1.validateConfiguration)(config, extension.validator);
253
+ let configError = await (0, validation_1.validateConfiguration)(config, extension.validator);
85
254
  if (configError) {
86
255
  return { success: false, message: "Config is not valid: " + configError };
87
256
  }
@@ -124,4 +293,4 @@ async function execExtension(args) {
124
293
  }
125
294
  return { success: true };
126
295
  }
127
- exports.execExtension = execExtension;
296
+ exports.execDestinationExtension = execDestinationExtension;
@@ -2,7 +2,8 @@ import { CommandRegistry } from "../../lib/command/types";
2
2
  import { JitsuExtensionExport } from "@jitsu/types/extension";
3
3
  import { Partial } from "rollup-plugin-typescript2/dist/partial";
4
4
  export declare const help: string;
5
- export declare const extensionCommands: CommandRegistry<"test" | "build" | "create" | "validate-config" | "exec">;
5
+ export declare const extensionCommands: CommandRegistry<"test" | "build" | "create" | "validate-config" | "exec" | "exec-src">;
6
6
  export declare function validateTsConfig(tsConfigPath: string): void;
7
7
  export declare function getDistFile(packageJson: any): any;
8
- export declare function loadBuild(code: string): Partial<JitsuExtensionExport>;
8
+ export declare function getConfigJson(jsonOrFile: string): any;
9
+ export declare function loadBuild(file: string): Promise<Partial<JitsuExtensionExport>>;
@@ -1,18 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.loadBuild = exports.getDistFile = exports.validateTsConfig = exports.extensionCommands = exports.help = void 0;
3
+ exports.loadBuild = exports.getConfigJson = exports.getDistFile = exports.validateTsConfig = exports.extensionCommands = exports.help = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
5
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
6
  const chalk_code_highlight_1 = require("../../lib/chalk-code-highlight");
7
- const fs = (0, tslib_1.__importStar)(require("fs"));
7
+ const fs = tslib_1.__importStar(require("fs"));
8
8
  const indent_1 = require("../../lib/indent");
9
9
  const create_1 = require("./create");
10
10
  const build_1 = require("./build");
11
11
  const test_1 = require("./test");
12
12
  const validate_config_1 = require("./validate-config");
13
13
  const template_1 = require("./template");
14
- const JSON5_1 = (0, tslib_1.__importDefault)(require("JSON5"));
14
+ const json5_1 = tslib_1.__importDefault(require("json5"));
15
15
  const exec_1 = require("./exec");
16
+ const readline = tslib_1.__importStar(require("readline"));
17
+ const sandbox_1 = require("@jitsu/node-bridge/sandbox");
16
18
  global.fetch = require("cross-fetch");
17
19
  const usage = `
18
20
  · ${chalk_1.default.bold("jitsu-cli extension create")}
@@ -58,9 +60,14 @@ ${chalk_1.default.bold("COMMANDS")} ${(0, indent_1.align)(usage, { indent: 2, ln
58
60
  `;
59
61
  exports.extensionCommands = {
60
62
  exec: {
61
- exec: exec_1.execExtension,
62
- description: "Execute extension of a test data",
63
- help: ""
63
+ exec: exec_1.execDestinationExtension,
64
+ description: "Execute destination extension on a test dataset",
65
+ help: "",
66
+ },
67
+ "exec-src": {
68
+ exec: exec_1.execSourceExtension,
69
+ description: "Builds and execute source connector extension with a test credentials and output data",
70
+ help: "",
64
71
  },
65
72
  test: {
66
73
  exec: test_1.test,
@@ -86,7 +93,7 @@ exports.extensionCommands = {
86
93
  function validateTsConfig(tsConfigPath) {
87
94
  let tsConfig;
88
95
  try {
89
- tsConfig = JSON5_1.default.parse(fs.readFileSync(tsConfigPath, "utf8"));
96
+ tsConfig = json5_1.default.parse(fs.readFileSync(tsConfigPath, "utf8"));
90
97
  }
91
98
  catch (e) {
92
99
  throw new Error(`${chalk_1.default.bold(tsConfigPath)} - syntax error: ${e.message}`);
@@ -100,10 +107,41 @@ function getDistFile(packageJson) {
100
107
  return packageJson.main || "dist/index.js";
101
108
  }
102
109
  exports.getDistFile = getDistFile;
103
- function loadBuild(code) {
104
- let f = new Function("exports", code);
105
- let exports = {};
106
- f(exports);
107
- return exports;
110
+ async function getFirstLine(pathToFile) {
111
+ const readable = fs.createReadStream(pathToFile);
112
+ const reader = readline.createInterface({ input: readable });
113
+ const line = await new Promise(resolve => {
114
+ reader.on("line", line => {
115
+ reader.close();
116
+ resolve(line);
117
+ });
118
+ });
119
+ readable.close();
120
+ return line;
121
+ }
122
+ function getConfigJson(jsonOrFile) {
123
+ if (jsonOrFile.trim().startsWith("{") && jsonOrFile.trim().endsWith("}")) {
124
+ return json5_1.default.parse(jsonOrFile.trim());
125
+ }
126
+ else {
127
+ if (!fs.existsSync(jsonOrFile)) {
128
+ throw new Error(`File ${jsonOrFile} does not exist!`);
129
+ }
130
+ return json5_1.default.parse(fs.readFileSync(jsonOrFile, "utf8"));
131
+ }
132
+ }
133
+ exports.getConfigJson = getConfigJson;
134
+ async function loadBuild(file) {
135
+ let formatDefinition = await getFirstLine(file);
136
+ if (formatDefinition.trim() === "//format=es" || formatDefinition.trim() === "//format=esm") {
137
+ return Promise.resolve().then(() => tslib_1.__importStar(require(file)));
138
+ }
139
+ else if (formatDefinition.trim() === "//format=cjs" || formatDefinition.trim() === "//format=commonjs") {
140
+ const vm = (0, sandbox_1.sandbox)({ file });
141
+ return vm.runFile(file);
142
+ }
143
+ else {
144
+ throw new Error(`Unsupported build format - ${formatDefinition}`);
145
+ }
108
146
  }
109
147
  exports.loadBuild = loadBuild;
@@ -1,27 +1,30 @@
1
1
  import { ProjectTemplate } from "../../lib/template";
2
- export declare type DestinationTemplateVars = {
2
+ export declare type TemplateVars = {
3
3
  license?: "MIT" | "Other";
4
4
  packageName: string;
5
- type: "destination" | "transform";
5
+ type: "destination" | "source" | "transform";
6
6
  jitsuVersion?: string;
7
7
  };
8
- export declare const packageJsonTemplate: ({ packageName, type, jitsuVersion }: DestinationTemplateVars) => {
8
+ export declare const packageJsonTemplate: ({ packageName, type, jitsuVersion }: TemplateVars) => {
9
9
  name: string;
10
10
  version: string;
11
11
  description: string;
12
12
  main: string;
13
13
  scripts: {
14
+ clean: string;
14
15
  build: string;
15
16
  test: string;
16
17
  "validate-config": string;
18
+ execute: string;
17
19
  };
18
20
  devDependencies: {
19
21
  "@jitsu/types": string;
20
- typescript: string;
21
- };
22
- dependencies: {
22
+ "@jitsu/jlib": string;
23
+ "ts-jest": string;
23
24
  "jitsu-cli": string;
24
25
  tslib: string;
26
+ typescript: string;
25
27
  };
28
+ dependencies: {};
26
29
  };
27
- export declare const extensionProjectTemplate: ProjectTemplate<DestinationTemplateVars>;
30
+ export declare const extensionProjectTemplate: ProjectTemplate<TemplateVars>;
@@ -8,18 +8,21 @@ const packageJsonTemplate = ({ packageName, type, jitsuVersion = undefined }) =>
8
8
  description: `Jitsu ${type} - ${packageName}`,
9
9
  main: `dist/${packageName}.js`,
10
10
  scripts: {
11
+ clean: "rm -rf ./dist",
11
12
  build: "jitsu-cli extension build",
12
13
  test: "jitsu-cli extension test",
13
14
  "validate-config": "jitsu-cli extension validate-config",
15
+ execute: `jitsu-cli extension ${type == "destination" ? "exec" : "exec-src"}`,
14
16
  },
15
17
  devDependencies: {
16
18
  "@jitsu/types": `${jitsuVersion || "^" + version_1.jitsuCliVersion}`,
17
- typescript: "^4.5.2",
18
- },
19
- dependencies: {
19
+ "@jitsu/jlib": `${jitsuVersion || "^" + version_1.jitsuCliVersion}`,
20
+ "ts-jest": "^27.0.7",
20
21
  "jitsu-cli": `${jitsuVersion || "^" + version_1.jitsuCliVersion}`,
21
22
  tslib: "^2.3.1",
23
+ typescript: "^4.5.2",
22
24
  },
25
+ dependencies: {},
23
26
  });
24
27
  exports.packageJsonTemplate = packageJsonTemplate;
25
28
  let destinationTest = ({ type = "destination" }) => {
@@ -72,6 +75,100 @@ let destinationCode = () => {
72
75
  };
73
76
  `;
74
77
  };
78
+ let sourceCode = () => {
79
+ return `
80
+ import { SourceCatalog, StateService, StreamReader, StreamSink, StreamConfiguration } from "@jitsu/types/sources";
81
+ import { ConfigValidationResult, ExtensionDescriptor } from "@jitsu/types/extension";
82
+
83
+ export interface SourceConfig {
84
+ user_id: string
85
+ my_source_param: string;
86
+ }
87
+
88
+ export interface StreamConfig {
89
+ my_stream_param: string;
90
+ }
91
+
92
+ async function validator(config: SourceConfig): Promise<ConfigValidationResult> {
93
+ //TODO: Check that provided config data allows to connect to third party API
94
+ console.log("validator is not yet implemented");
95
+ return true;
96
+ }
97
+
98
+ const descriptor: ExtensionDescriptor<SourceConfig> = {
99
+ id: "my_source",
100
+ displayName: "Source Example",
101
+ description:
102
+ "Example source that produces row with run number and source/stream configuration.",
103
+ configurationParameters: [
104
+ {
105
+ displayName: "User ID",
106
+ id: "user_id",
107
+ type: "string",
108
+ required: true,
109
+ documentation: "User Id",
110
+ },
111
+ {
112
+ displayName: "Example Parameter",
113
+ id: "my_source_param",
114
+ required: true,
115
+ type: "string",
116
+ documentation: \`
117
+ <div>
118
+ Example Parameter
119
+ </div>
120
+ \`,
121
+ }
122
+ ],
123
+ };
124
+
125
+ const sourceCatalog: SourceCatalog<SourceConfig, StreamConfig> = async config => {
126
+ return [
127
+ {
128
+ type: "my_source_runs",
129
+ supportedModes: ["incremental"],
130
+ params: [
131
+ {
132
+ id: "my_stream_param",
133
+ displayName: "Stream Parameter",
134
+ type: "string",
135
+ documentation: \`
136
+ <div>
137
+ Stream Parameter example.
138
+ </div>
139
+ \`,
140
+ required: true,
141
+ },
142
+ ]
143
+ }
144
+ ];
145
+ };
146
+
147
+ const streamReader: StreamReader<SourceConfig, StreamConfig> = async (
148
+ sourceConfig: SourceConfig,
149
+ streamType: string,
150
+ streamConfiguration: StreamConfiguration<StreamConfig>,
151
+ streamSink: StreamSink,
152
+ services: { state: StateService }
153
+ ) => {
154
+ //Example of saved state usage. Read previous run number:
155
+ let runNumber = services.state.get("run_number") || 0;
156
+ runNumber++
157
+ streamSink.log("INFO", "Run number: " + runNumber);
158
+ streamSink.addRecord({
159
+ $id: runNumber,
160
+ $recordTimestamp: new Date(),
161
+ type: streamType,
162
+ ...sourceConfig,
163
+ ...streamConfiguration.parameters
164
+ });
165
+ //Save last run number to state
166
+ services.state.set("run_number", runNumber);
167
+ };
168
+
169
+ export { streamReader, sourceCatalog, descriptor, validator };
170
+ `;
171
+ };
75
172
  let transformCode = () => {
76
173
  return `
77
174
  import {Destination, DestinationMessage, JitsuDestinationContext} from "@jitsu/types/destination";
@@ -124,7 +221,7 @@ exports.extensionProjectTemplate = {
124
221
  "__test__/destination.test.ts": destinationTest,
125
222
  "src/destination.ts": vars => vars.type == "destination" && destinationCode(),
126
223
  "src/transform.ts": vars => vars.type == "transform" && transformCode(),
127
- "src/index.ts": vars => descriptor[vars.type](vars),
224
+ "src/index.ts": vars => (vars.type == "source" ? sourceCode() : descriptor[vars.type](vars)),
128
225
  "package.json": exports.packageJsonTemplate,
129
226
  "tsconfig.json": {
130
227
  compilerOptions: {
@@ -2,10 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.test = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const path_1 = (0, tslib_1.__importDefault)(require("path"));
6
- const log_1 = (0, tslib_1.__importDefault)(require("../../lib/log"));
7
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
8
- const fs_1 = (0, tslib_1.__importDefault)(require("fs"));
5
+ const path_1 = tslib_1.__importDefault(require("path"));
6
+ const log_1 = tslib_1.__importDefault(require("../../lib/log"));
7
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
+ const fs_1 = tslib_1.__importDefault(require("fs"));
9
9
  const jest_cli_1 = require("jest-cli");
10
10
  const _1 = require("./");
11
11
  async function test(args) {
@@ -24,7 +24,7 @@ async function test(args) {
24
24
  };
25
25
  }
26
26
  (0, _1.validateTsConfig)(tsConfigPath);
27
- let jestArgs = ["--passWithNoTests", "--projects", projectBase];
27
+ const jestArgs = ["--passWithNoTests", "--projects", projectBase];
28
28
  if (typescriptEnabled) {
29
29
  jestArgs.push("--preset", "ts-jest");
30
30
  }
@@ -2,47 +2,36 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateConfig = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const commander_1 = (0, tslib_1.__importDefault)(require("commander"));
6
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
7
- const path_1 = (0, tslib_1.__importDefault)(require("path"));
8
- const fs_1 = (0, tslib_1.__importDefault)(require("fs"));
9
- const JSON5_1 = (0, tslib_1.__importDefault)(require("JSON5"));
10
- const log_1 = (0, tslib_1.__importDefault)(require("../../lib/log"));
5
+ const commander_1 = tslib_1.__importDefault(require("commander"));
6
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
+ const path_1 = tslib_1.__importDefault(require("path"));
8
+ const fs_1 = tslib_1.__importDefault(require("fs"));
9
+ const json5_1 = tslib_1.__importDefault(require("json5"));
10
+ const log_1 = tslib_1.__importDefault(require("../../lib/log"));
11
11
  const index_1 = require("./index");
12
- const validator_helper_1 = require("../../lib/validator-helper");
12
+ const validation_1 = require("../../lib/validation");
13
13
  async function validateConfig(args) {
14
14
  const program = new commander_1.default.Command();
15
15
  program.option("-d, --dir <project_dir>", "Project directory");
16
- program.option("-c, --config <config_file>", "Configuration file");
17
- program.option("-o, --config-object <config_json>", "Inline extension configuration JSON");
16
+ program.option("-c, --config <config_file_or_json>", "Configuration file path or inline extension configuration JSON");
18
17
  program.argument("[project_dir]");
19
18
  program.parse(["dummy", "dummy", ...args]);
20
19
  const opts = program.opts();
21
- if (!opts.configObject && !opts.config) {
20
+ if (!opts.config) {
22
21
  return {
23
22
  success: false,
24
- message: 'Please define config object either with -j "{embedded json}", or with -f json_file',
23
+ message: "Please define config object -c json_file_path or -c '{json_object:}'",
25
24
  };
26
25
  }
27
26
  let configObj;
28
- if (opts.configObject) {
29
- try {
30
- configObj = JSON5_1.default.parse(opts.configObject);
31
- }
32
- catch (e) {
33
- return { success: false, message: `Malformed json (-j): ${e.message}` };
34
- }
27
+ try {
28
+ configObj = (0, index_1.getConfigJson)(opts.config);
35
29
  }
36
- else {
37
- if (!fs_1.default.existsSync(opts.config)) {
38
- return { success: false, message: `${opts.config} (-f) doesn't exist!` };
39
- }
40
- try {
41
- configObj = JSON5_1.default.parse(fs_1.default.readFileSync(opts.config, "utf8"));
42
- }
43
- catch (e) {
44
- return { success: false, message: `Malformed json in file ${opts.config} (-f): ${e.message}` };
45
- }
30
+ catch (e) {
31
+ return {
32
+ success: false,
33
+ message: `Can't parse config JSON: '${opts.config}' ${e.message})`,
34
+ };
46
35
  }
47
36
  let projectDir = opts.dir || ".";
48
37
  (0, log_1.default)().info("Project dir: " + projectDir);
@@ -50,21 +39,20 @@ async function validateConfig(args) {
50
39
  if (!fs_1.default.existsSync(packageFile)) {
51
40
  return { success: false, message: `Can't find package file ${packageFile}` };
52
41
  }
53
- let packageObj = JSON5_1.default.parse(fs_1.default.readFileSync(packageFile, "utf8"));
42
+ let packageObj = json5_1.default.parse(fs_1.default.readFileSync(packageFile, "utf8"));
54
43
  let distFile = path_1.default.resolve(projectDir, (0, index_1.getDistFile)(packageObj));
55
44
  (0, log_1.default)().info("Dist file: " + distFile);
56
45
  if (!fs_1.default.existsSync(distFile)) {
57
46
  return { success: false, message: `Can't find dist file (${distFile}). Forgot to run jitsu-cli extension build ?` };
58
47
  }
59
48
  (0, log_1.default)().info("🤔 Loading build from " + chalk_1.default.bold(distFile));
60
- let build = (0, index_1.loadBuild)(fs_1.default.readFileSync(distFile, "utf8"));
49
+ let build = await (0, index_1.loadBuild)(distFile);
61
50
  (0, log_1.default)().info("👍 Module loaded!");
62
51
  if (!build.validator) {
63
52
  return { success: false, message: "Build doesn't export validator symbol" };
64
53
  }
65
- (0, log_1.default)().info("🤔 Validating configuration " +
66
- (opts.config ? `from file ${path_1.default.resolve(projectDir, opts.config)}` : JSON.stringify(configObj)));
67
- let validationError = await (0, validator_helper_1.validateConfiguration)(configObj, build.validator);
54
+ (0, log_1.default)().info("🤔 Validating configuration " + JSON.stringify(configObj));
55
+ let validationError = await (0, validation_1.validateConfiguration)(configObj, build.validator);
68
56
  if (validationError) {
69
57
  return { success: false, message: `❌ ${validationError}` };
70
58
  }
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.chalkCode = exports.defaultColorScheme = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const prismjs_1 = (0, tslib_1.__importDefault)(require("prismjs"));
6
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
5
+ const prismjs_1 = tslib_1.__importDefault(require("prismjs"));
6
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
7
  exports.defaultColorScheme = {
8
8
  punctuation: "#999",
9
9
  operator: "#9a6e3a",
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.subcommands = exports.executeCommand = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
5
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
6
  const version_1 = require("../version");
7
7
  function captureCommand(command, args) {
8
8
  let commandParts = command.split(" ");
@@ -71,9 +71,11 @@ function displayHelp(commands, helpOpts, cmd) {
71
71
  }
72
72
  }
73
73
  const executeCommand = async (commands, args, helpOpts) => {
74
- let newVersion = await (0, version_1.hasNewerVersion)();
75
- if (newVersion) {
76
- console.log((0, version_1.getUpgradeMessage)(newVersion));
74
+ if (version_1.jitsuCliVersion !== "0.0.0") {
75
+ const newVersion = await (0, version_1.hasNewerVersion)();
76
+ if (newVersion) {
77
+ console.log((0, version_1.getUpgradeMessage)(newVersion, version_1.jitsuCliVersion));
78
+ }
77
79
  }
78
80
  if (args.length === 0 || isHelpOption(args[0])) {
79
81
  displayHelp(commands, helpOpts);
package/lib/lib/indent.js CHANGED
@@ -28,7 +28,7 @@ function align(text, { indent = 0, lnBefore = 0, lnAfter = 0 } = {}) {
28
28
  }
29
29
  exports.align = align;
30
30
  function jsonify(obj) {
31
- if (typeof obj === 'string') {
31
+ if (typeof obj === "string") {
32
32
  try {
33
33
  return JSON.parse(obj);
34
34
  }
package/lib/lib/log.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export declare type Log = {
2
2
  debug: (msg?: string, ...args: any[]) => void;
3
3
  info: (msg?: string, ...args: any[]) => void;
4
+ warn: (msg?: string, ...args: any[]) => void;
4
5
  spinInfo: (...args: string[]) => void;
5
6
  error: (...args: string[]) => void;
6
7
  };
package/lib/lib/log.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
4
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
5
5
  function log(delegate, styling, msg, args) {
6
6
  if (!msg) {
7
7
  delegate("");
@@ -20,6 +20,9 @@ function getLog() {
20
20
  error(msg, ...args) {
21
21
  log(console.error, { prefix: "error", color: "red" }, msg, args);
22
22
  },
23
+ warn(msg, ...args) {
24
+ log(console.warn, { prefix: "warn ", color: "yellow" }, msg, args);
25
+ },
23
26
  spinInfo(args) { },
24
27
  info(msg, ...args) {
25
28
  log(console.info, { prefix: "info ", color: "cyan" }, msg, args);
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.write = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const posix_1 = (0, tslib_1.__importDefault)(require("path/posix"));
6
- const fs = (0, tslib_1.__importStar)(require("fs"));
5
+ const path_1 = tslib_1.__importDefault(require("path"));
6
+ const fs = tslib_1.__importStar(require("fs"));
7
7
  const indent_1 = require("./indent");
8
8
  function toTemplateFunction(template) {
9
9
  if (template === null || template === undefined) {
@@ -18,8 +18,8 @@ function toTemplateFunction(template) {
18
18
  }
19
19
  function write(dir, template, vars) {
20
20
  Object.entries(template).forEach(([fileName, template]) => {
21
- let filePath = posix_1.default.resolve(dir, fileName);
22
- let fileDir = posix_1.default.dirname(filePath);
21
+ let filePath = path_1.default.resolve(dir, fileName);
22
+ let fileDir = path_1.default.dirname(filePath);
23
23
  if (!fs.existsSync(fileDir)) {
24
24
  fs.mkdirSync(fileDir, { recursive: true });
25
25
  }
@@ -0,0 +1,2 @@
1
+ import { ConfigValidator } from "@jitsu/types/extension";
2
+ export declare function validateConfiguration<Config>(config: Config, validator: ConfigValidator): Promise<string | undefined>;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateConfiguration = void 0;
4
+ async function validateConfiguration(config, validator) {
5
+ let validationResult;
6
+ try {
7
+ validationResult = await validator(config);
8
+ }
9
+ catch (e) {
10
+ return e?.message || "Unknown exception";
11
+ }
12
+ if (validationResult === true) {
13
+ return undefined;
14
+ }
15
+ if (typeof validationResult === "string") {
16
+ return validationResult;
17
+ }
18
+ if (typeof validationResult === "object" && !validationResult.ok) {
19
+ return validationResult.message ?? "Unknown error";
20
+ }
21
+ return undefined;
22
+ }
23
+ exports.validateConfiguration = validateConfiguration;
@@ -1,5 +1,5 @@
1
1
  export declare const jitsuCliVersion: string;
2
2
  export declare const jitsuPackageName: string;
3
- export declare function getUpgradeMessage(newVersion: string): string;
3
+ export declare function getUpgradeMessage(newVersion: string, oldVersion: string): string;
4
4
  export declare function box(msg: string): string;
5
5
  export declare function hasNewerVersion(): Promise<string | undefined>;
@@ -2,16 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasNewerVersion = exports.box = exports.getUpgradeMessage = exports.jitsuPackageName = exports.jitsuCliVersion = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const package_json_1 = (0, tslib_1.__importDefault)(require("../../package.json"));
6
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
7
- const log_1 = (0, tslib_1.__importDefault)(require("./log"));
8
- const preload_1 = (0, tslib_1.__importDefault)(require("semver/preload"));
5
+ const package_json_1 = tslib_1.__importDefault(require("../../package.json"));
6
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
+ const log_1 = tslib_1.__importDefault(require("./log"));
8
+ const preload_1 = tslib_1.__importDefault(require("semver/preload"));
9
9
  const fetch = require("cross-fetch");
10
10
  exports.jitsuCliVersion = package_json_1.default.version;
11
11
  exports.jitsuPackageName = package_json_1.default.name;
12
12
  let newVersion = undefined;
13
- function getUpgradeMessage(newVersion) {
14
- return box(`🚀 New version of Jitsu CLI is available: ${newVersion}.\n Run ${chalk_1.default.bold("npm install -g " + exports.jitsuPackageName)} or ${chalk_1.default.bold("yarn global install " + exports.jitsuPackageName)}`);
13
+ function getUpgradeMessage(newVersion, oldVersion) {
14
+ return box(`🚀 New version of Jitsu CLI is available: ${oldVersion} → ${chalk_1.default.green(newVersion)} \n Run ${chalk_1.default.bold("npm install -g " + exports.jitsuPackageName)} or ${chalk_1.default.bold("yarn global install " + exports.jitsuPackageName)}`);
15
15
  }
16
16
  exports.getUpgradeMessage = getUpgradeMessage;
17
17
  function padRight(str, minLen, symbol = " ") {
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jitsu-cli",
3
- "version": "0.6.0",
3
+ "version": "0.0.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -8,7 +8,7 @@
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "https://github.com/jitsucom/jitsu-sdk",
11
- "directory": "packages/jitsu-cli"
11
+ "directory": "core/jitsu-cli"
12
12
  },
13
13
  "bugs": {
14
14
  "url": "https://github.com/jitsucom/jitsu/issues"
@@ -22,13 +22,14 @@
22
22
  "bin"
23
23
  ],
24
24
  "scripts": {
25
- "build": "yarn clean:some && tsc -p . && mv ./lib/src/* ./lib/ && rmdir ./lib/src/",
26
- "global": "yarn install -g",
27
- "clean:some": "rm -rf ./lib",
25
+ "build": "tsc -p . && mv ./lib/src/* ./lib/ && rmdir ./lib/src/",
26
+ "clean": "rm -rf ./lib",
28
27
  "start": "ts-node src/index.ts",
28
+ "cli": "node lib/index.js",
29
29
  "test": "jest --verbose ./__tests__"
30
30
  },
31
31
  "devDependencies": {
32
+ "@jitsu/types": "workspace:*",
32
33
  "@babel/preset-env": "^7.16.4",
33
34
  "@babel/preset-typescript": "^7.16.0",
34
35
  "@types/commander": "^2.12.2",
@@ -37,15 +38,19 @@
37
38
  "@types/jest-cli": "^24.3.0",
38
39
  "@types/validate-npm-package-name": "^3.0.3",
39
40
  "child_process": "^1.0.2",
40
- "lerna": "^4.0.0",
41
41
  "ts-node": "^10.4.0"
42
42
  },
43
43
  "dependencies": {
44
- "@rollup/plugin-commonjs": "^21.0.1",
44
+ "@jitsu/jlib": "workspace:*",
45
+ "@jitsu/node-bridge": "workspace:*",
46
+ "@rollup/plugin-commonjs": "^22.0.0-14",
47
+ "@rollup/plugin-inject": "^4.0.4",
48
+ "@rollup/plugin-json": "^4.1.0",
45
49
  "@rollup/plugin-multi-entry": "^4.1.0",
46
50
  "@rollup/plugin-node-resolve": "^13.0.6",
47
51
  "@types/prismjs": "^1.16.6",
48
52
  "chalk": "^4.1.2",
53
+ "cli-table": "latest",
49
54
  "commander": "^8.3.0",
50
55
  "cross-fetch": "^3.1.4",
51
56
  "inquirer": "^8.2.0",
@@ -64,6 +69,5 @@
64
69
  "tslib": "^2.3.1",
65
70
  "typescript": "^4.5.2",
66
71
  "validate-npm-package-name": "^3.0.0"
67
- },
68
- "gitHead": "4a5222ce49da3cb6be58648c78b1111b39764fe1"
72
+ }
69
73
  }
package/lib/run.js CHANGED
@@ -2,10 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.run = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
5
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
6
  const command_1 = require("./lib/command");
7
7
  const extension_1 = require("./cli/extension");
8
- const log_1 = (0, tslib_1.__importDefault)(require("./lib/log"));
8
+ const log_1 = tslib_1.__importDefault(require("./lib/log"));
9
9
  const version_1 = require("./lib/version");
10
10
  const commands = {
11
11
  extension: (0, command_1.subcommands)(extension_1.extensionCommands, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jitsu-cli",
3
- "version": "0.7.2",
3
+ "version": "0.9.0-alpha.169",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -8,7 +8,7 @@
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "https://github.com/jitsucom/jitsu-sdk",
11
- "directory": "packages/jitsu-cli"
11
+ "directory": "core/jitsu-cli"
12
12
  },
13
13
  "bugs": {
14
14
  "url": "https://github.com/jitsucom/jitsu/issues"
@@ -21,14 +21,8 @@
21
21
  "lib",
22
22
  "bin"
23
23
  ],
24
- "scripts": {
25
- "build": "yarn clean:some && tsc -p . && mv ./lib/src/* ./lib/ && rmdir ./lib/src/",
26
- "global": "yarn install -g",
27
- "clean:some": "rm -rf ./lib",
28
- "start": "ts-node src/index.ts",
29
- "test": "jest --verbose ./__tests__"
30
- },
31
24
  "devDependencies": {
25
+ "@jitsu/types": "0.9.0-alpha.169",
32
26
  "@babel/preset-env": "^7.16.4",
33
27
  "@babel/preset-typescript": "^7.16.0",
34
28
  "@types/commander": "^2.12.2",
@@ -37,15 +31,19 @@
37
31
  "@types/jest-cli": "^24.3.0",
38
32
  "@types/validate-npm-package-name": "^3.0.3",
39
33
  "child_process": "^1.0.2",
40
- "lerna": "^4.0.0",
41
34
  "ts-node": "^10.4.0"
42
35
  },
43
36
  "dependencies": {
44
- "@rollup/plugin-commonjs": "^21.0.1",
37
+ "@jitsu/jlib": "0.9.0-alpha.169",
38
+ "@jitsu/node-bridge": "0.9.0-alpha.169",
39
+ "@rollup/plugin-commonjs": "^22.0.0-14",
40
+ "@rollup/plugin-inject": "^4.0.4",
41
+ "@rollup/plugin-json": "^4.1.0",
45
42
  "@rollup/plugin-multi-entry": "^4.1.0",
46
43
  "@rollup/plugin-node-resolve": "^13.0.6",
47
44
  "@types/prismjs": "^1.16.6",
48
45
  "chalk": "^4.1.2",
46
+ "cli-table": "latest",
49
47
  "commander": "^8.3.0",
50
48
  "cross-fetch": "^3.1.4",
51
49
  "inquirer": "^8.2.0",
@@ -65,5 +63,11 @@
65
63
  "typescript": "^4.5.2",
66
64
  "validate-npm-package-name": "^3.0.0"
67
65
  },
68
- "gitHead": "30a19db8beb48804efb33653bf9ed85d7c3aa751"
69
- }
66
+ "scripts": {
67
+ "build": "tsc -p . && mv ./lib/src/* ./lib/ && rmdir ./lib/src/",
68
+ "clean": "rm -rf ./lib",
69
+ "start": "ts-node src/index.ts",
70
+ "cli": "node lib/index.js",
71
+ "test": "jest --verbose ./__tests__"
72
+ }
73
+ }
@@ -1,3 +0,0 @@
1
- import { ConfigValidationResult, ConfigValidator } from "@jitsu/types/extension";
2
- export declare function validationResultToError(validationResult: ConfigValidationResult): string | undefined;
3
- export declare function validateConfiguration(config: any, validator: ConfigValidator): Promise<(string | undefined)>;
@@ -1,21 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateConfiguration = exports.validationResultToError = void 0;
4
- function validationResultToError(validationResult) {
5
- if (typeof validationResult === "boolean" && !validationResult) {
6
- return "Config is not valid, an exact reason isn't specified by validator";
7
- }
8
- else if (typeof validationResult === "string") {
9
- return "Config is not valid: " + validationResult;
10
- }
11
- else if (typeof validationResult === "object" && !validationResult.ok) {
12
- return "Config is not valid: " + validationResult.message;
13
- }
14
- return undefined;
15
- }
16
- exports.validationResultToError = validationResultToError;
17
- async function validateConfiguration(config, validator) {
18
- let validationResult = await validator(config);
19
- return validationResultToError(validationResult);
20
- }
21
- exports.validateConfiguration = validateConfiguration;