@snowplow/snowtype 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,57 @@
1
+ # Snowplow Personal & Academic License Agreement
2
+
3
+ _Version 1.0, September 2023_
4
+
5
+ ## Acceptance
6
+
7
+ In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
8
+
9
+ ## Copyright License
10
+
11
+ The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it, but only for any non-commercial purpose.
12
+
13
+ Non-commercial purposes include only:
14
+
15
+ * Personal use for research, experiment, personal study, or hobby projects, without any anticipated commercial application.
16
+ * Use for teaching purposes by lecturers of a school or university.
17
+ * Use to evaluate the sufficiency of the software for the commercial needs of you or your company.
18
+
19
+ ## Notices
20
+
21
+ You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above.
22
+
23
+ ## Patent License
24
+
25
+ The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software for a non-commercial purpose.
26
+
27
+ ## Fair Use
28
+
29
+ You may have "fair use" rights for the software under the law. These terms do not limit them.
30
+
31
+ ## No Other Rights
32
+
33
+ These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
34
+
35
+ ## Patent Defense
36
+
37
+ If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
38
+
39
+ ## Violations
40
+
41
+ The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
42
+
43
+ ## No Liability
44
+
45
+ **As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.**
46
+
47
+ ## Definitions
48
+
49
+ The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
50
+
51
+ **You** refers to the individual or entity agreeing to these terms.
52
+
53
+ **Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
54
+
55
+ **Your licenses** are all the licenses granted to you for the software under these terms.
56
+
57
+ **Use** means anything you do with the software requiring one of your licenses.
package/bin/bin ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ require("../dist/index.js");
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ConsoleAPI = void 0;
7
+ const got_1 = __importDefault(require("got"));
8
+ const utils_1 = require("../utils");
9
+ class ConsoleAPI {
10
+ apiKey;
11
+ organizationId;
12
+ accessToken;
13
+ apiHost = "https://console.snowplowanalytics.com/api/msc";
14
+ constructor({ apiKey, organizationId }) {
15
+ this.apiKey = apiKey;
16
+ this.organizationId = organizationId;
17
+ }
18
+ async fetchAccessToken() {
19
+ if (this.accessToken) {
20
+ return this.accessToken;
21
+ }
22
+ const accessTokenUrl = `${this.apiHost}/v1/organizations/${this.organizationId}/credentials/v2/token`;
23
+ const { accessToken } = await (0, got_1.default)(accessTokenUrl, {
24
+ headers: { "X-API-Key": this.apiKey },
25
+ }).json();
26
+ this.accessToken = accessToken;
27
+ return accessToken;
28
+ }
29
+ /* TODO allow for adding params in the resourceUrl before reaching fetchResource */
30
+ async fetchResource(resourceUrl) {
31
+ const token = await this.fetchAccessToken();
32
+ return (0, got_1.default)(resourceUrl, {
33
+ headers: { Authorization: "Bearer " + token },
34
+ }).json();
35
+ }
36
+ /* Todo, return schema type */
37
+ async fetchSchemaVersion({ schema, }) {
38
+ const { vendor, name, format, version } = (0, utils_1.splitIgluSchemaUrlParts)(schema);
39
+ const schemaSHA256 = (0, utils_1.hashSHA256)(`${this.organizationId}-${vendor}-${name}-${format}`);
40
+ const schemaVersionUrl = `${this.apiHost}/v1/organizations/${this.organizationId}/data-structures/v1/${schemaSHA256}/versions/${version}`;
41
+ return await this.fetchResource(schemaVersionUrl);
42
+ }
43
+ async fetchSchemaHash({ schema }) {
44
+ const { vendor, name, format } = (0, utils_1.splitIgluSchemaUrlParts)(schema);
45
+ const schemaSHA256 = (0, utils_1.hashSHA256)(`${this.organizationId}-${vendor}-${name}-${format}`);
46
+ const schemaVersionUrl = `${this.apiHost}/v1/organizations/${this.organizationId}/data-structures/v1/${schemaSHA256}`;
47
+ return await this.fetchResource(schemaVersionUrl);
48
+ }
49
+ async fetchTrackingScenario({ scenarioId }) {
50
+ const schemaVersionUrl = `${this.apiHost}/v1/organizations/${this.organizationId}/tracking-scenarios/v1/${scenarioId}`;
51
+ return await this.fetchResource(schemaVersionUrl);
52
+ }
53
+ // TODO - refine all of it
54
+ async authenticate() {
55
+ return this.fetchAccessToken()
56
+ .then((token) => !!token)
57
+ .catch(() => false);
58
+ }
59
+ }
60
+ exports.ConsoleAPI = ConsoleAPI;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.fetchIgluCentralSchema = void 0;
7
+ const got_1 = __importDefault(require("got"));
8
+ async function fetchIgluCentralSchema({ schema, }) {
9
+ return (await (0, got_1.default)(`https://raw.githubusercontent.com/snowplow/iglu-central/master/schemas/${schema.replace("iglu:", "")}`)).body;
10
+ }
11
+ exports.fetchIgluCentralSchema = fetchIgluCentralSchema;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./fetchIgluCentralSchema"), exports);
18
+ __exportStar(require("./ConsoleAPI"), exports);
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkScenarioUpdates = exports.createStorageJSON = exports.checkDataStructureUpdates = exports.addConfigAttribute = exports.createConfigFile = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const utils_1 = require("../utils");
7
+ const DEFAULT_CONFIG_NAME = 'snowtype.config.json';
8
+ const DEFAULT_CONFIG = {
9
+ tracker: "@snowplow/browser-tracker",
10
+ language: "typescript",
11
+ outpath: "./snowtype"
12
+ };
13
+ const DEFAULT_STORAGE_FILE = '.snowtype-lock.json';
14
+ function writeToConfig(config) {
15
+ (0, fs_1.writeFileSync)((0, path_1.resolve)(process.cwd(), `./${DEFAULT_CONFIG_NAME}`), JSON.stringify(config, null, 2));
16
+ }
17
+ function createConfigFile(partialConfig) {
18
+ const config = { ...DEFAULT_CONFIG, ...partialConfig };
19
+ try {
20
+ writeToConfig(config);
21
+ return true;
22
+ }
23
+ catch (error) {
24
+ console.error(error);
25
+ return false;
26
+ }
27
+ }
28
+ exports.createConfigFile = createConfigFile;
29
+ // TODO refactor file stuff
30
+ function addConfigAttribute(attribute, value) {
31
+ try {
32
+ const rawConfig = (0, fs_1.readFileSync)((0, path_1.resolve)(process.cwd(), `./${DEFAULT_CONFIG_NAME}`), { encoding: "utf-8" });
33
+ const parsedConfig = JSON.parse(rawConfig);
34
+ const valueExists = parsedConfig[attribute].some(entry => entry === value);
35
+ if (!valueExists) {
36
+ parsedConfig[attribute].push(value);
37
+ }
38
+ // TODO, run validate after patch and if failed abort ?
39
+ writeToConfig(parsedConfig);
40
+ return true;
41
+ }
42
+ catch (error) {
43
+ console.error(error);
44
+ return false;
45
+ }
46
+ }
47
+ exports.addConfigAttribute = addConfigAttribute;
48
+ /**
49
+ *
50
+ *
51
+ * @export
52
+ * @param {ConsoleAPI} consoleApi
53
+ * @param {string[]} dataStructures Array with Console data structure iglu URLs
54
+ * @return {*} {Promise<string[]>}
55
+ */
56
+ async function checkDataStructureUpdates(consoleApi, dataStructures) {
57
+ // Should we store the time we fetched the previous URL ?
58
+ // Does newest means by time uploaded or by version, should this be an option ?
59
+ const schemaUpdates = await Promise.all(dataStructures.map(async (dataStructureUrl) => {
60
+ const { version } = (0, utils_1.splitIgluSchemaUrlParts)(dataStructureUrl);
61
+ const { deployments } = (await consoleApi.fetchSchemaHash({ schema: dataStructureUrl }));
62
+ // Should we get only PROD ? (PROLLY)
63
+ // With one pass, find the latest.
64
+ const latestDeployment = deployments.reduce((accum, cur) => {
65
+ const currentTs = new Date(cur.ts);
66
+ if (currentTs > new Date(accum.ts)) {
67
+ return cur;
68
+ }
69
+ return accum;
70
+ }, deployments[0]);
71
+ if (latestDeployment.version === version) {
72
+ return {
73
+ previous: dataStructureUrl,
74
+ next: dataStructureUrl
75
+ };
76
+ }
77
+ return {
78
+ previous: dataStructureUrl,
79
+ next: (0, utils_1.replaceIgluSchemaPart)(dataStructureUrl, { version: latestDeployment.version })
80
+ };
81
+ }));
82
+ return schemaUpdates;
83
+ }
84
+ exports.checkDataStructureUpdates = checkDataStructureUpdates;
85
+ // the storage JSON file. Will it go on the `snowtype` folder or in a `.snowtype` directory ?
86
+ function createStorageJSON({ trackingScenarios }) {
87
+ try {
88
+ const latestGenerationConfig = { trackingScenarios: trackingScenarios.map(ts => ({ [ts.id]: ts.version })) };
89
+ (0, fs_1.writeFileSync)((0, path_1.resolve)(process.cwd(), `./${DEFAULT_CONFIG_NAME}/${DEFAULT_STORAGE_FILE}`), JSON.stringify(latestGenerationConfig, null, 2));
90
+ return true;
91
+ }
92
+ catch (error) {
93
+ console.error(error);
94
+ return false;
95
+ }
96
+ }
97
+ exports.createStorageJSON = createStorageJSON;
98
+ // replace latestGenerationConfig type with what we decide. Created from createStorageJSON
99
+ // Just check if there is any update ? The generator for now will regenerate all anyway.
100
+ async function checkScenarioUpdates(consoleApi, trackingScenarioIds, latestGenerationConfig) {
101
+ // trackingScenarios would be [ts.id]: ts.version
102
+ const { trackingScenarios } = latestGenerationConfig;
103
+ const updates = {};
104
+ await Promise.all(trackingScenarioIds.map(async (trackingScenarioId) => {
105
+ const existingScenarioGeneratedVersion = trackingScenarios[trackingScenarioId];
106
+ // should we check if trackingScenarioId exists in the storage, and if not notify for update ?
107
+ if (!existingScenarioGeneratedVersion) {
108
+ return trackingScenarioId;
109
+ }
110
+ const scenario = (await consoleApi.fetchTrackingScenario({ scenarioId: trackingScenarioId })).data[0];
111
+ if ((scenario.version || 0) > existingScenarioGeneratedVersion) {
112
+ updates[trackingScenarioId] = {
113
+ previous: existingScenarioGeneratedVersion,
114
+ next: scenario.version
115
+ };
116
+ }
117
+ return trackingScenarioId;
118
+ }));
119
+ return updates;
120
+ }
121
+ exports.checkScenarioUpdates = checkScenarioUpdates;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TRACKER_LANGUAGES = exports.DEFAULT_LOCK = exports.DEFAULT_FILENAME = exports.DEFAULT_STORAGE_FILENAME = exports.DEFAULT_CONFIG_NAME = void 0;
4
+ exports.DEFAULT_CONFIG_NAME = 'snowtype.config.json';
5
+ exports.DEFAULT_STORAGE_FILENAME = '.snowtype-lock.json';
6
+ exports.DEFAULT_FILENAME = 'snowplow';
7
+ exports.DEFAULT_LOCK = '.snowtype.json';
8
+ exports.TRACKER_LANGUAGES = {
9
+ '@snowplow/javascript-tracker': [
10
+ {
11
+ value: 'javascript',
12
+ name: 'JavaScript'
13
+ }
14
+ ],
15
+ '@snowplow/browser-tracker': [
16
+ {
17
+ value: 'javascript',
18
+ name: 'JavaScript'
19
+ },
20
+ {
21
+ value: 'typescript',
22
+ name: 'TypeScript'
23
+ }
24
+ ],
25
+ '@snowplow/node-tracker': [
26
+ {
27
+ value: 'javascript',
28
+ name: 'JavaScript'
29
+ },
30
+ {
31
+ value: 'typescript',
32
+ name: 'TypeScript'
33
+ }
34
+ ],
35
+ 'snowplow-android-tracker': [
36
+ {
37
+ value: 'kotlin',
38
+ name: 'Kotlin'
39
+ }
40
+ ],
41
+ 'snowplow-ios-tracker': [
42
+ {
43
+ value: 'swift',
44
+ name: 'Swift'
45
+ }
46
+ ],
47
+ 'snowplow-golang-tracker': [
48
+ {
49
+ value: 'go',
50
+ name: 'Go'
51
+ }
52
+ ]
53
+ };
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.act = void 0;
4
+ const logger_1 = require("../logger");
5
+ const utils_1 = require("./utils");
6
+ function act(action) {
7
+ return (options, cmd) => {
8
+ const globalOptions = (0, utils_1.getGlobalOptions)(cmd);
9
+ const logging = (0, logger_1.createLogger)();
10
+ const spinner = (0, utils_1.createSpinner)();
11
+ const logger = logging.withVerbosity(globalOptions.verbose);
12
+ const apiKey = globalOptions.apiKey;
13
+ return action(apiKey, logger, spinner, options)
14
+ .then(() => stopSpinner(spinner))
15
+ .catch((err) => {
16
+ errHandle(err, logger, spinner);
17
+ });
18
+ };
19
+ }
20
+ exports.act = act;
21
+ function errHandle(err, logger, spinner) {
22
+ stopSpinner(spinner);
23
+ logger.error(err);
24
+ throw err;
25
+ }
26
+ function stopSpinner(spinner) {
27
+ if (spinner.isSpinning() === true) {
28
+ spinner.stop(true);
29
+ }
30
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateAction = exports.execGenerate = void 0;
4
+ const process_1 = require("process");
5
+ const path_1 = require("path");
6
+ const fs_1 = require("fs");
7
+ const mkdirp_1 = require("mkdirp");
8
+ const snowtype_core_1 = require("@snowplow/snowtype-core");
9
+ const api_1 = require("../../api");
10
+ const errors_1 = require("../../errors");
11
+ const constants_1 = require("./constants");
12
+ const utils_1 = require("./utils");
13
+ const dispatch_1 = require("./dispatch");
14
+ function checkGenerateOptions(logger) {
15
+ logger.debug("Checking for existing configuration..");
16
+ (0, utils_1.guardConfigExistsValid)();
17
+ logger.success("Valid configuration found");
18
+ }
19
+ async function execGenerate(apiKey, logger, spinner) {
20
+ checkGenerateOptions(logger);
21
+ spinner.setSpinnerTitle("Generating...");
22
+ if (spinner.isSpinning() === false) {
23
+ spinner.start();
24
+ }
25
+ const config = (0, utils_1.getConfig)();
26
+ if ((0, utils_1.isEmpty)(config.dataStructures) &&
27
+ (0, utils_1.isEmpty)(config.igluCentralSchemas) &&
28
+ (0, utils_1.isEmpty)(config.trackingScenarioIds)) {
29
+ logger.warn("Data Structures, Schemas and Tracking Scenarios are empty.");
30
+ }
31
+ const consoleApi = new api_1.ConsoleAPI({
32
+ apiKey,
33
+ organizationId: config.organizationId,
34
+ });
35
+ // we could also throw properly in api
36
+ const isAuthenticated = await consoleApi.authenticate();
37
+ if (!isAuthenticated) {
38
+ throw new errors_1.SnowtypeAuthError();
39
+ }
40
+ const dataProducts = await (0, utils_1.mkDataProducts)(consoleApi, config.trackingScenarioIds);
41
+ const igluSchemas = await (0, utils_1.mkIgluSchemas)(config.igluCentralSchemas);
42
+ const dataStructures = await (0, utils_1.mkDataStructures)(consoleApi, config.dataStructures);
43
+ const genCfg = {
44
+ language: config.language,
45
+ tracker: config.tracker,
46
+ schemas: [...igluSchemas, ...dataStructures],
47
+ dataProducts,
48
+ };
49
+ const generationOutput = await (0, snowtype_core_1.generate)(genCfg);
50
+ logger.success("Code generated, writing...");
51
+ const output = generationOutput?.lines.join("\n");
52
+ const trueDir = (0, path_1.resolve)((0, process_1.cwd)(), config.outpath);
53
+ mkdirp_1.mkdirp.sync(trueDir);
54
+ const trueFile = constants_1.DEFAULT_FILENAME + (0, utils_1.getExtension)(config.language);
55
+ (0, fs_1.writeFileSync)((0, path_1.resolve)(trueDir, trueFile), output);
56
+ (0, utils_1.writeLockFile)(dataProducts, config.outpath);
57
+ }
58
+ exports.execGenerate = execGenerate;
59
+ exports.generateAction = (0, dispatch_1.act)(execGenerate);
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.patchAction = exports.generateAction = exports.updateAction = exports.initAction = void 0;
4
+ var init_1 = require("./init");
5
+ Object.defineProperty(exports, "initAction", { enumerable: true, get: function () { return init_1.initAction; } });
6
+ var update_1 = require("./update");
7
+ Object.defineProperty(exports, "updateAction", { enumerable: true, get: function () { return update_1.updateAction; } });
8
+ var generate_1 = require("./generate");
9
+ Object.defineProperty(exports, "generateAction", { enumerable: true, get: function () { return generate_1.generateAction; } });
10
+ var patch_1 = require("./patch");
11
+ Object.defineProperty(exports, "patchAction", { enumerable: true, get: function () { return patch_1.patchAction; } });
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initAction = void 0;
4
+ const prompts_1 = require("@inquirer/prompts");
5
+ const errors_1 = require("../../errors");
6
+ const api_1 = require("../../api");
7
+ const config_1 = require("../../config");
8
+ const constants_1 = require("./constants");
9
+ const utils_1 = require("./utils");
10
+ const types_1 = require("./types");
11
+ const dispatch_1 = require("./dispatch");
12
+ const initPrompts = [
13
+ {
14
+ type: "password",
15
+ message: "Enter your Snowplow organization ID:",
16
+ mask: true,
17
+ validate: utils_1.isNonEmpty,
18
+ },
19
+ {
20
+ type: "select",
21
+ message: "Select the Snowplow Tracker to use:",
22
+ choices: [
23
+ {
24
+ value: "@snowplow/javascript-tracker",
25
+ name: "JavaScript Tracker",
26
+ },
27
+ {
28
+ value: "@snowplow/browser-tracker",
29
+ name: "Browser Tracker",
30
+ },
31
+ {
32
+ value: "@snowplow/node-tracker",
33
+ name: "Node Tracker",
34
+ },
35
+ {
36
+ value: "snowplow-android-tracker",
37
+ name: "Android Tracker",
38
+ },
39
+ {
40
+ value: "snowplow-ios-tracker",
41
+ name: "iOS Tracker",
42
+ },
43
+ {
44
+ value: "snowplow-golang-tracker",
45
+ name: "Golang Tracker",
46
+ },
47
+ ],
48
+ },
49
+ {
50
+ // placeholder
51
+ type: "select",
52
+ message: "Select the language to use:",
53
+ },
54
+ {
55
+ type: "input",
56
+ message: "Enter the directory for Snowtype output:",
57
+ default: "./snowtype",
58
+ },
59
+ ];
60
+ const defaultOptions = {
61
+ organizationId: "",
62
+ tracker: "",
63
+ language: "",
64
+ outpath: "",
65
+ };
66
+ function getOrAsk(key, opts, inquire, override = "") {
67
+ if (override) {
68
+ return Promise.resolve(override);
69
+ }
70
+ // @ts-expect-error index signature
71
+ if (Object.prototype.hasOwnProperty.call(opts, key) && opts[key] != null) {
72
+ // @ts-expect-error index signature
73
+ const provided = opts[key];
74
+ if (typeof provided === "string") {
75
+ return Promise.resolve(provided);
76
+ }
77
+ throw new errors_1.SnowtypeInternalError("Invalid default options.");
78
+ }
79
+ if ((0, types_1.isInputPrompt)(inquire)) {
80
+ return (0, prompts_1.input)(inquire);
81
+ }
82
+ if ((0, types_1.isPasswordPrompt)(inquire)) {
83
+ return (0, prompts_1.password)(inquire);
84
+ }
85
+ if ((0, types_1.isSelectPrompt)(inquire)) {
86
+ return (0, prompts_1.select)(inquire);
87
+ }
88
+ throw new errors_1.SnowtypeInternalError("Unknown Prompt inquired.");
89
+ }
90
+ function mkChoices(languages, prompt) {
91
+ if ((0, types_1.isSelectPrompt)(prompt)) {
92
+ prompt.choices = languages;
93
+ }
94
+ return prompt;
95
+ }
96
+ async function checkInitOptions(options, logger) {
97
+ const initOptions = { ...defaultOptions };
98
+ logger.debug("Checking for existing configuration file..");
99
+ (0, utils_1.guardConfigNotExistsValid)();
100
+ const orgId = await getOrAsk("organizationId", options, initPrompts[0]);
101
+ initOptions.organizationId = orgId;
102
+ const tracker = await getOrAsk("tracker", options, initPrompts[1]);
103
+ if (!(0, utils_1.isValidTracker)(tracker)) {
104
+ throw new errors_1.SnowtypeOptionError("tracker", tracker);
105
+ }
106
+ initOptions.tracker = tracker;
107
+ const langs = constants_1.TRACKER_LANGUAGES[tracker];
108
+ if (!Array.isArray(langs) || langs.length === 0) {
109
+ throw new errors_1.SnowtypeInternalError("Missing language entry.");
110
+ }
111
+ let language;
112
+ if (langs.length === 1) {
113
+ const languageSelection = langs[0];
114
+ if (typeof languageSelection === "undefined") {
115
+ throw new errors_1.SnowtypeInternalError("Missing language.");
116
+ }
117
+ language = await getOrAsk("language", options, initPrompts[2], languageSelection.value);
118
+ }
119
+ else {
120
+ language = await getOrAsk("language", options, mkChoices(langs, initPrompts[2]));
121
+ }
122
+ if (!(0, utils_1.isValidLanguage)(initOptions.tracker, language)) {
123
+ throw new errors_1.SnowtypeOptionError("language", language);
124
+ }
125
+ initOptions.language = language;
126
+ const outpath = await getOrAsk("outpath", options, initPrompts[3]);
127
+ initOptions.outpath = outpath;
128
+ logger.debug("Assempling initialization options..");
129
+ return initOptions;
130
+ }
131
+ async function execInit(apiKey, logger, spinner, options) {
132
+ const initOpts = await checkInitOptions(options, logger);
133
+ spinner.setSpinnerTitle("Initialising...");
134
+ if (spinner.isSpinning() === false) {
135
+ spinner.start();
136
+ }
137
+ logger.debug("Creating configuration with options: ".concat(JSON.stringify(initOpts)));
138
+ const config = (0, utils_1.completeInitConfig)(initOpts);
139
+ // @ts-expect-error fix
140
+ (0, config_1.validateConfig)(config);
141
+ const consoleApi = new api_1.ConsoleAPI({
142
+ apiKey,
143
+ organizationId: config.organizationId,
144
+ });
145
+ const isAuthenticated = await consoleApi.authenticate();
146
+ if (!isAuthenticated) {
147
+ throw new errors_1.SnowtypeAuthError();
148
+ }
149
+ logger.success("Authentication succeeded");
150
+ (0, utils_1.writeConfigToFile)(config);
151
+ logger.success("Configuration created");
152
+ }
153
+ exports.initAction = (0, dispatch_1.act)(execInit);
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.patchAction = void 0;
4
+ const command_utils_1 = require("../../command-utils");
5
+ const errors_1 = require("../../errors");
6
+ const generate_1 = require("./generate");
7
+ const utils_1 = require("./utils");
8
+ const dispatch_1 = require("./dispatch");
9
+ const defaultOptions = {
10
+ trackingScenarioIds: [],
11
+ dataStructures: [],
12
+ igluCentralSchemas: [],
13
+ yes: false
14
+ };
15
+ function checkPatchOptions(options, logger) {
16
+ const patchOptions = { ...defaultOptions, ...options };
17
+ if (Object.values(patchOptions).every((v) => typeof v === 'boolean' || v.length === 0)) {
18
+ throw new errors_1.SnowtypeMissingOptionsError();
19
+ }
20
+ logger.debug("Checking for existing configuration..");
21
+ (0, utils_1.guardConfigExistsValid)();
22
+ logger.success("Valid configuration found");
23
+ return patchOptions;
24
+ }
25
+ function execPatch(apiKey, logger, spinner, options) {
26
+ const patchOptions = checkPatchOptions(options, logger);
27
+ logger.debug("Starting patch process with options: ".concat(JSON.stringify(patchOptions)));
28
+ const patchEntries = Object.entries(patchOptions);
29
+ patchEntries.forEach(([key, value]) => {
30
+ if (key !== "yes" && Array.isArray(value) && value.length !== 0) {
31
+ value.forEach((element) => {
32
+ (0, command_utils_1.addConfigAttribute)(key, element);
33
+ });
34
+ }
35
+ });
36
+ logger.success("Configuration patched");
37
+ if (patchOptions.yes === true) {
38
+ return (0, generate_1.execGenerate)(apiKey, logger, spinner);
39
+ }
40
+ else {
41
+ logger.log("Code is not generated yet for the patched configuration");
42
+ }
43
+ return Promise.resolve(undefined);
44
+ }
45
+ exports.patchAction = (0, dispatch_1.act)(execPatch);
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isSelectPrompt = exports.isConfirmPrompt = exports.isPasswordPrompt = exports.isInputPrompt = void 0;
4
+ function isInputPrompt(p) {
5
+ return p.type === 'input';
6
+ }
7
+ exports.isInputPrompt = isInputPrompt;
8
+ function isPasswordPrompt(p) {
9
+ return p.type === 'password';
10
+ }
11
+ exports.isPasswordPrompt = isPasswordPrompt;
12
+ function isConfirmPrompt(p) {
13
+ return p.type === 'confirm';
14
+ }
15
+ exports.isConfirmPrompt = isConfirmPrompt;
16
+ function isSelectPrompt(p) {
17
+ return p.type === 'select';
18
+ }
19
+ exports.isSelectPrompt = isSelectPrompt;