@wiztivi/dana-cli 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/addDevice/deviceConfig/androidtvConfig.d.ts +0 -4
- package/dist/commands/addDevice/deviceConfig/androidtvConfig.js +2 -8
- package/dist/commands/addDevice/deviceConfig/configTypes.d.ts +12 -1
- package/dist/commands/addDevice/deviceConfig/tizenConfig.js +34 -3
- package/dist/commands/addDevice/helper/addDeviceHelper.d.ts +12 -0
- package/dist/commands/addDevice/helper/addDeviceHelper.js +19 -0
- package/dist/commands/authentication/AuthenticationManager.d.ts +23 -0
- package/dist/commands/authentication/AuthenticationManager.js +107 -0
- package/dist/commands/authentication/authDefinition.js +17 -3
- package/dist/commands/authentication/authHook.d.ts +1 -1
- package/dist/commands/authentication/authHook.js +17 -4
- package/dist/commands/authentication/commands/get-packages-token.d.ts +6 -0
- package/dist/commands/authentication/commands/get-packages-token.js +30 -0
- package/dist/commands/authentication/commands/login.js +13 -89
- package/dist/commands/authentication/commands/logout.d.ts +5 -0
- package/dist/commands/authentication/commands/logout.js +20 -0
- package/dist/commands/authentication/helper/CommandHelper.d.ts +1 -0
- package/dist/commands/authentication/helper/CommandHelper.js +8 -0
- package/dist/commands/authentication/helper/CredentialsHelper.d.ts +18 -5
- package/dist/commands/authentication/helper/CredentialsHelper.js +55 -5
- package/dist/commands/createApp/helpers/CreateAppHelper.d.ts +0 -1
- package/dist/common/const/deviceConst.js +1 -1
- package/dist/common/const/exitCodeConst.d.ts +1 -0
- package/dist/common/const/exitCodeConst.js +1 -0
- package/dist/common/helpers/CreateFileHelper.js +1 -1
- package/dist/common/helpers/InstallHelper.d.ts +1 -0
- package/dist/common/helpers/InstallHelper.js +15 -3
- package/dist/common/helpers/UpdateFileHelper.js +11 -3
- package/dist/common/helpers/UserInputGetter.js +4 -1
- package/dist/common/helpers/stringHelper.d.ts +5 -0
- package/dist/common/helpers/stringHelper.js +12 -0
- package/dist/common/translation/en.json +4 -2
- package/package.json +2 -2
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
import fs from "node:fs";
|
|
13
13
|
import path from "node:path";
|
|
14
14
|
import DeviceConfig from "./deviceConfig.js";
|
|
15
|
-
import { DEFAULT_IMAGE_URL } from "../../createApp/const/setupConst.js";
|
|
16
15
|
import ComponentHelper from "../../addComponent/helper/ComponentHelper.js";
|
|
17
16
|
import * as prompts from "@clack/prompts";
|
|
18
17
|
import colors from "picocolors";
|
|
@@ -24,13 +23,8 @@ import { CredentialsHelper } from "../../authentication/helper/CredentialsHelper
|
|
|
24
23
|
import { ListPackageVersionsCommand } from "@aws-sdk/client-codeartifact";
|
|
25
24
|
import { createCodeArtifactClient } from "../../authentication/helper/CodeArtifactHelper.js";
|
|
26
25
|
import { DOMAIN, DOMAIN_OWNER } from "../../authentication/authentConst.js";
|
|
26
|
+
import addDeviceHelper from "../helper/addDeviceHelper.js";
|
|
27
27
|
const AndroidtvConfig = class extends DeviceConfig {
|
|
28
|
-
/**
|
|
29
|
-
* Get the app icon url
|
|
30
|
-
*/
|
|
31
|
-
static _getAppIcon = () => {
|
|
32
|
-
return Promise.resolve(DEFAULT_IMAGE_URL);
|
|
33
|
-
};
|
|
34
28
|
/**
|
|
35
29
|
* Ask the appId
|
|
36
30
|
*/
|
|
@@ -122,7 +116,7 @@ const AndroidtvConfig = class extends DeviceConfig {
|
|
|
122
116
|
appName: () => this._askAppName(),
|
|
123
117
|
appVersion: () => this._askAppVersion(),
|
|
124
118
|
appVersionCode: () => this._askAppVersionCode(),
|
|
125
|
-
icon: () =>
|
|
119
|
+
icon: () => addDeviceHelper.getAppIcon(),
|
|
126
120
|
wtvAndroidVersion: () => this._getWtvAndroidVersion(),
|
|
127
121
|
}, {
|
|
128
122
|
onCancel: () => {
|
|
@@ -9,8 +9,19 @@ interface AndroidDevice {
|
|
|
9
9
|
interface AndroidConfig {
|
|
10
10
|
device: AndroidDevice;
|
|
11
11
|
}
|
|
12
|
+
interface TizenDevice {
|
|
13
|
+
type?: string;
|
|
14
|
+
profileName?: string;
|
|
15
|
+
icon: string;
|
|
16
|
+
application: {
|
|
17
|
+
requiredVersion: string;
|
|
18
|
+
package: string;
|
|
19
|
+
id: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
12
22
|
interface TizenConf {
|
|
13
23
|
renderers: string[];
|
|
24
|
+
device: TizenDevice;
|
|
14
25
|
}
|
|
15
26
|
interface WebosConf {
|
|
16
27
|
device: WebosDevice;
|
|
@@ -24,4 +35,4 @@ interface WebosDevice {
|
|
|
24
35
|
largeIcon: string;
|
|
25
36
|
disableBackHistoryAPI: boolean;
|
|
26
37
|
}
|
|
27
|
-
export { AndroidDevice, AndroidConfig, TizenConf, WebosConf, WebosDevice };
|
|
38
|
+
export { AndroidDevice, AndroidConfig, TizenConf, TizenDevice, WebosConf, WebosDevice };
|
|
@@ -13,6 +13,11 @@ import fs from "node:fs";
|
|
|
13
13
|
import path from "node:path";
|
|
14
14
|
import DeviceConfig from "./deviceConfig.js";
|
|
15
15
|
import { LIGHTNING } from "../../../common/const/deviceConst.js";
|
|
16
|
+
import * as prompts from "@clack/prompts";
|
|
17
|
+
import colors from "picocolors";
|
|
18
|
+
import addDeviceHelper from "../helper/addDeviceHelper.js";
|
|
19
|
+
import { validAppVersion, validInputLength } from "../../../common/helpers/InputValidator.js";
|
|
20
|
+
import { clean } from "semver-ts";
|
|
16
21
|
const TizenConfig = class extends DeviceConfig {
|
|
17
22
|
static appConfig = {
|
|
18
23
|
css: {
|
|
@@ -34,16 +39,42 @@ const TizenConfig = class extends DeviceConfig {
|
|
|
34
39
|
},
|
|
35
40
|
},
|
|
36
41
|
};
|
|
37
|
-
static getConfig = () => {
|
|
38
|
-
|
|
42
|
+
static getConfig = async () => {
|
|
43
|
+
prompts.log.info(colors.bold("Let's configure Tizen !"));
|
|
44
|
+
const applicationConfig = await prompts.group({
|
|
45
|
+
requiredVersion: async () => {
|
|
46
|
+
const requiredVersion = await addDeviceHelper.promptTextFactory({
|
|
47
|
+
promptMessage: "What is the application requiredVersion ?",
|
|
48
|
+
validationFunction: (value) => validAppVersion(value),
|
|
49
|
+
placeholder: "1.0.0",
|
|
50
|
+
initialValue: "1.0.0",
|
|
51
|
+
});
|
|
52
|
+
return clean(requiredVersion);
|
|
53
|
+
},
|
|
54
|
+
package: async () => addDeviceHelper.promptTextFactory({
|
|
55
|
+
errorMessage: "Package name is required !",
|
|
56
|
+
promptMessage: "What is the package name ? Should be unique.",
|
|
57
|
+
validationFunction: (value) => validInputLength(value, "Package name is required !"),
|
|
58
|
+
}),
|
|
59
|
+
id: async () => addDeviceHelper.promptTextFactory({
|
|
60
|
+
errorMessage: "Package id is required !",
|
|
61
|
+
promptMessage: "What is the package id ?",
|
|
62
|
+
validationFunction: (value) => validInputLength(value, "Package id is required !"),
|
|
63
|
+
}),
|
|
64
|
+
});
|
|
65
|
+
return {
|
|
39
66
|
renderers: [LIGHTNING],
|
|
67
|
+
device: {
|
|
68
|
+
icon: await addDeviceHelper.getAppIcon(),
|
|
69
|
+
application: { ...applicationConfig },
|
|
70
|
+
},
|
|
40
71
|
};
|
|
41
|
-
return Promise.resolve(tizenConfig);
|
|
42
72
|
};
|
|
43
73
|
static setConfig = ({ directory, config }) => {
|
|
44
74
|
const filePath = path.join(directory, "profiles", "app.config.tizen.json");
|
|
45
75
|
let jsonData = JSON.parse(fs.readFileSync(filePath).toString());
|
|
46
76
|
jsonData = this.updateProfileJsonWithRenderers(jsonData, config.renderers);
|
|
77
|
+
jsonData.tizen.device = { ...jsonData.tizen.device, ...config.device };
|
|
47
78
|
fs.writeFileSync(filePath, JSON.stringify(jsonData, null, 4));
|
|
48
79
|
return Promise.resolve("Tizen configuration done");
|
|
49
80
|
};
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export interface PromptFactoryParams {
|
|
2
|
+
errorMessage?: string;
|
|
3
|
+
promptMessage: string;
|
|
4
|
+
validationFunction: (value: string, errorMessage?: string) => string | undefined;
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
initialValue?: string;
|
|
7
|
+
}
|
|
1
8
|
declare const AddDeviceHelper: {
|
|
2
9
|
new (): {};
|
|
3
10
|
/**
|
|
@@ -9,5 +16,10 @@ declare const AddDeviceHelper: {
|
|
|
9
16
|
* We use script so we can get renderers for smartTv
|
|
10
17
|
*/
|
|
11
18
|
readonly getInstalledDevices: (directory: string) => string[];
|
|
19
|
+
/**
|
|
20
|
+
* Get the app icon url
|
|
21
|
+
*/
|
|
22
|
+
readonly getAppIcon: () => Promise<string>;
|
|
23
|
+
readonly promptTextFactory: ({ errorMessage, promptMessage, validationFunction, placeholder, initialValue, }: PromptFactoryParams) => Promise<string>;
|
|
12
24
|
};
|
|
13
25
|
export default AddDeviceHelper;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import * as prompts from "@clack/prompts";
|
|
5
|
+
import { DEFAULT_IMAGE_URL } from "../../createApp/const/setupConst.js";
|
|
6
|
+
import ComponentHelper from "../../addComponent/helper/ComponentHelper.js";
|
|
4
7
|
const AddDeviceHelper = class {
|
|
5
8
|
/**
|
|
6
9
|
* clean on error
|
|
@@ -30,5 +33,21 @@ const AddDeviceHelper = class {
|
|
|
30
33
|
}
|
|
31
34
|
return installedDevices;
|
|
32
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* Get the app icon url
|
|
38
|
+
*/
|
|
39
|
+
static getAppIcon = () => {
|
|
40
|
+
return Promise.resolve(DEFAULT_IMAGE_URL);
|
|
41
|
+
};
|
|
42
|
+
static promptTextFactory = async ({ errorMessage, promptMessage, validationFunction, placeholder, initialValue, }) => {
|
|
43
|
+
const result = (await prompts.text({
|
|
44
|
+
message: promptMessage,
|
|
45
|
+
placeholder,
|
|
46
|
+
initialValue,
|
|
47
|
+
validate: (value) => validationFunction(value, errorMessage),
|
|
48
|
+
}));
|
|
49
|
+
ComponentHelper.handleCancellation(result);
|
|
50
|
+
return result;
|
|
51
|
+
};
|
|
33
52
|
};
|
|
34
53
|
export default AddDeviceHelper;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AwsCredentials, DanaToken } from "./helper/CredentialsHelper.js";
|
|
2
|
+
import { JwtPayload } from "jsonwebtoken";
|
|
3
|
+
export interface CognitoIdToken extends JwtPayload {
|
|
4
|
+
given_name: string;
|
|
5
|
+
family_name: string;
|
|
6
|
+
email: string;
|
|
7
|
+
}
|
|
8
|
+
export interface AuthCredentials {
|
|
9
|
+
aws: AwsCredentials;
|
|
10
|
+
dana: DanaToken;
|
|
11
|
+
org: string;
|
|
12
|
+
}
|
|
13
|
+
export declare class AuthenticationManager {
|
|
14
|
+
private static getAPIURL;
|
|
15
|
+
static login(organization: string): Promise<AuthCredentials>;
|
|
16
|
+
static logout(organization: string, creds?: Partial<DanaToken>): Promise<void>;
|
|
17
|
+
static refresh(organization: string, token: string): Promise<AuthCredentials>;
|
|
18
|
+
static isTokenExpired(token: string): boolean;
|
|
19
|
+
static loginNPM(organization: string, credentials: AwsCredentials): Promise<{
|
|
20
|
+
token: string;
|
|
21
|
+
expiration?: Date;
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import getPort from "get-port";
|
|
2
|
+
import express from "express";
|
|
3
|
+
import { CredentialsHelper } from "./helper/CredentialsHelper.js";
|
|
4
|
+
import open from "open";
|
|
5
|
+
import jwt from "jsonwebtoken";
|
|
6
|
+
import { createCodeArtifactClient, getRepositoryEndpoint } from "./helper/CodeArtifactHelper.js";
|
|
7
|
+
import { GetAuthorizationTokenCommand } from "@aws-sdk/client-codeartifact";
|
|
8
|
+
import { DOMAIN, DOMAIN_OWNER } from "./authentConst.js";
|
|
9
|
+
import { execSync } from "node:child_process";
|
|
10
|
+
export class AuthenticationManager {
|
|
11
|
+
static getAPIURL(organization) {
|
|
12
|
+
return `https://api.${organization}.dana-framework.com`; // Or http://localhost:3001
|
|
13
|
+
}
|
|
14
|
+
static async login(organization) {
|
|
15
|
+
const app = express();
|
|
16
|
+
app.disable("x-powered-by");
|
|
17
|
+
const promise = new Promise((resolve, reject) => {
|
|
18
|
+
const timeout = setTimeout(() => {
|
|
19
|
+
reject(new Error("Login timed out."));
|
|
20
|
+
}, 5 * 60 * 1000);
|
|
21
|
+
app.get("/callback", (req, res) => {
|
|
22
|
+
clearTimeout(timeout);
|
|
23
|
+
try {
|
|
24
|
+
if (req.query.error) {
|
|
25
|
+
res.send("Login failed. Check the CLI for details.");
|
|
26
|
+
return reject(new Error(req.query.error));
|
|
27
|
+
}
|
|
28
|
+
const token = JSON.parse(req.query.token);
|
|
29
|
+
const awsCredentials = JSON.parse(req.query.aws);
|
|
30
|
+
const creds = { aws: awsCredentials, dana: token, org: organization };
|
|
31
|
+
res.send("Login successful! You can close this window.");
|
|
32
|
+
CredentialsHelper.store(creds);
|
|
33
|
+
resolve(creds);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
res.send("Login failed. Check the CLI for details.");
|
|
37
|
+
reject(err);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
const port = await getPort();
|
|
42
|
+
const server = app.listen(port);
|
|
43
|
+
await open(`${AuthenticationManager.getAPIURL(organization)}/login?port=${port}`);
|
|
44
|
+
return promise.finally(() => {
|
|
45
|
+
server.closeAllConnections();
|
|
46
|
+
server.close();
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
static async logout(organization, creds) {
|
|
50
|
+
const url = new URL(`${AuthenticationManager.getAPIURL(organization)}/logout`);
|
|
51
|
+
if (creds?.id_token) {
|
|
52
|
+
url.searchParams.append("id_token", creds.id_token);
|
|
53
|
+
}
|
|
54
|
+
if (creds?.refresh_token) {
|
|
55
|
+
url.searchParams.append("refresh_token", creds.refresh_token);
|
|
56
|
+
}
|
|
57
|
+
await open(url.toString());
|
|
58
|
+
CredentialsHelper.delete(organization);
|
|
59
|
+
}
|
|
60
|
+
static async refresh(organization, token) {
|
|
61
|
+
const data = await fetch(`${AuthenticationManager.getAPIURL(organization)}/login?refresh_token=${token}`);
|
|
62
|
+
if (!data.ok) {
|
|
63
|
+
return AuthenticationManager.login(organization);
|
|
64
|
+
}
|
|
65
|
+
const refreshedCreds = (await data.json());
|
|
66
|
+
const creds = {
|
|
67
|
+
aws: refreshedCreds.aws,
|
|
68
|
+
dana: {
|
|
69
|
+
...refreshedCreds.token,
|
|
70
|
+
refresh_token: token,
|
|
71
|
+
},
|
|
72
|
+
org: organization,
|
|
73
|
+
};
|
|
74
|
+
CredentialsHelper.store(creds);
|
|
75
|
+
return creds;
|
|
76
|
+
}
|
|
77
|
+
static isTokenExpired(token) {
|
|
78
|
+
const payload = jwt.decode(token);
|
|
79
|
+
if (!payload.exp) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
const expirationDate = new Date(payload.exp * 1000);
|
|
83
|
+
return expirationDate <= new Date();
|
|
84
|
+
}
|
|
85
|
+
static async loginNPM(organization, credentials) {
|
|
86
|
+
// Create CodeArtifact client with credentials
|
|
87
|
+
const client = createCodeArtifactClient(credentials);
|
|
88
|
+
// Get authorization token
|
|
89
|
+
const tokenCommand = new GetAuthorizationTokenCommand({
|
|
90
|
+
domain: DOMAIN,
|
|
91
|
+
domainOwner: DOMAIN_OWNER,
|
|
92
|
+
});
|
|
93
|
+
const { authorizationToken, expiration } = await client.send(tokenCommand);
|
|
94
|
+
if (!authorizationToken) {
|
|
95
|
+
throw new Error("Authorization token not found");
|
|
96
|
+
}
|
|
97
|
+
// Get repository endpoint
|
|
98
|
+
const repositoryEndpoint = await getRepositoryEndpoint({ organization, credentials, client, format: "npm" });
|
|
99
|
+
// Configure npm with the repository and token
|
|
100
|
+
execSync(`npm config set @dana:registry=${repositoryEndpoint}`);
|
|
101
|
+
execSync(`npm config set //${repositoryEndpoint.replace(/^https?:\/\//, "")}:_authToken=${authorizationToken}`);
|
|
102
|
+
return {
|
|
103
|
+
token: authorizationToken,
|
|
104
|
+
expiration,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -1,19 +1,33 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
1
|
+
import { Command, Option } from "commander";
|
|
2
2
|
import translation from "../../common/translation/translation.js";
|
|
3
3
|
import login from "./commands/login.js";
|
|
4
4
|
import { statusAction } from "./commands/status.js";
|
|
5
|
-
import
|
|
5
|
+
import logout from "./commands/logout.js";
|
|
6
|
+
import { getPackagesToken } from "./commands/get-packages-token.js";
|
|
7
|
+
import { authHook } from "./authHook.js";
|
|
6
8
|
const addAuthDefinition = () => {
|
|
7
9
|
const command = new Command("auth").description(translation["command.auth.description"]);
|
|
8
10
|
const loginCmd = new Command("login")
|
|
9
11
|
.description(translation["command.auth.login.description"])
|
|
10
|
-
.option("-o, --org <organization>", translation["command.auth.login.option.org"]
|
|
12
|
+
.option("-o, --org <organization>", translation["command.auth.login.option.org"])
|
|
11
13
|
.action(login);
|
|
12
14
|
command.addCommand(loginCmd);
|
|
15
|
+
const logoutCmd = new Command("logout")
|
|
16
|
+
.description(translation["command.auth.logout.description"])
|
|
17
|
+
.option("-o, --org <organization>", translation["command.auth.login.option.org"])
|
|
18
|
+
.action(logout);
|
|
19
|
+
command.addCommand(logoutCmd);
|
|
13
20
|
const statusCmd = new Command("status")
|
|
14
21
|
.description(translation["command.auth.status.description"])
|
|
15
22
|
.action(statusAction);
|
|
16
23
|
command.addCommand(statusCmd);
|
|
24
|
+
const getPackagesTokenCmd = new Command("get-packages-token")
|
|
25
|
+
.description(translation["command.auth.get-packages-token.description"])
|
|
26
|
+
.addOption(new Option("-t, --target <target>", "Packages target").makeOptionMandatory(true).choices(["android"]))
|
|
27
|
+
.option("-o, --org <organization>", translation["command.auth.login.option.org"])
|
|
28
|
+
.hook("preAction", authHook)
|
|
29
|
+
.action(getPackagesToken);
|
|
30
|
+
command.addCommand(getPackagesTokenCmd);
|
|
17
31
|
return command;
|
|
18
32
|
};
|
|
19
33
|
export default addAuthDefinition;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const authHook: () => void
|
|
1
|
+
export declare const authHook: () => Promise<void>;
|
|
@@ -9,11 +9,24 @@
|
|
|
9
9
|
* This software MAY NOT be used, modified or rewritten without prior written permission from Wiztivi.
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
|
-
import
|
|
12
|
+
import * as prompts from "@clack/prompts";
|
|
13
|
+
import { CredentialsHelper } from "./helper/CredentialsHelper.js";
|
|
14
|
+
import { AuthenticationManager } from "./AuthenticationManager.js";
|
|
13
15
|
import { LOGIN_ERROR } from "../../common/const/exitCodeConst.js";
|
|
14
|
-
export const authHook = () => {
|
|
15
|
-
const
|
|
16
|
-
|
|
16
|
+
export const authHook = async () => {
|
|
17
|
+
const credentials = CredentialsHelper.get();
|
|
18
|
+
try {
|
|
19
|
+
if (!credentials.dana?.id_token || !credentials.dana?.refresh_token) {
|
|
20
|
+
await AuthenticationManager.login(credentials.org);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (AuthenticationManager.isTokenExpired(credentials.dana.id_token) ||
|
|
24
|
+
(credentials.aws && new Date(credentials.aws.expiration) < new Date())) {
|
|
25
|
+
await AuthenticationManager.refresh(credentials.org, credentials.dana.refresh_token);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
prompts.log.error(error.message);
|
|
17
30
|
process.exit(LOGIN_ERROR);
|
|
18
31
|
}
|
|
19
32
|
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { CredentialsHelper } from "../helper/CredentialsHelper.js";
|
|
2
|
+
import { createCodeArtifactClient } from "../helper/CodeArtifactHelper.js";
|
|
3
|
+
import { GetAuthorizationTokenCommand } from "@aws-sdk/client-codeartifact";
|
|
4
|
+
import * as prompts from "@clack/prompts";
|
|
5
|
+
import { GET_PACKAGES_TOKEN_ERROR } from "../../../common/const/exitCodeConst.js";
|
|
6
|
+
import { DOMAIN, DOMAIN_OWNER } from "../authentConst.js";
|
|
7
|
+
const getAndroidToken = async (creds) => {
|
|
8
|
+
const client = createCodeArtifactClient(creds);
|
|
9
|
+
const command = new GetAuthorizationTokenCommand({
|
|
10
|
+
domain: DOMAIN,
|
|
11
|
+
domainOwner: DOMAIN_OWNER,
|
|
12
|
+
});
|
|
13
|
+
try {
|
|
14
|
+
const result = await client.send(command);
|
|
15
|
+
console.log(result.authorizationToken);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
prompts.log.error(error.message);
|
|
19
|
+
process.exit(GET_PACKAGES_TOKEN_ERROR);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const getPackagesToken = async (options) => {
|
|
23
|
+
const creds = CredentialsHelper.get(options.org);
|
|
24
|
+
switch (options.target) {
|
|
25
|
+
case "android":
|
|
26
|
+
// authHook ensure credentials are valid
|
|
27
|
+
return getAndroidToken(creds.aws);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
export { getPackagesToken };
|
|
@@ -1,103 +1,27 @@
|
|
|
1
|
-
import { GetAuthorizationTokenCommand } from "@aws-sdk/client-codeartifact";
|
|
2
1
|
import * as prompts from "@clack/prompts";
|
|
3
|
-
import { execSync } from "node:child_process";
|
|
4
|
-
import express from "express";
|
|
5
|
-
import getPort from "get-port";
|
|
6
|
-
import open from "open";
|
|
7
2
|
import colors from "picocolors";
|
|
8
|
-
import { LOGIN_ERROR } from "../../../common/const/exitCodeConst.js";
|
|
9
3
|
import { CredentialsHelper } from "../helper/CredentialsHelper.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
4
|
+
import { AuthenticationManager } from "../AuthenticationManager.js";
|
|
5
|
+
import { handleError } from "../helper/CommandHelper.js";
|
|
12
6
|
/*
|
|
13
7
|
Login to DANA backend (with aws and cognito) and connect to npm codeartifact
|
|
14
8
|
More info: https://github.com/wiztivi-rd/dana-cli/wiki/Login
|
|
15
9
|
*/
|
|
16
|
-
const login = async ({ org
|
|
17
|
-
const
|
|
18
|
-
const credentials = CredentialsHelper.get();
|
|
19
|
-
if (credentials) {
|
|
20
|
-
try {
|
|
21
|
-
if (new Date(credentials.aws.expiration) < new Date()) {
|
|
22
|
-
const data = await fetch(`${apiUrl}/login?refresh_token=${credentials.dana.refresh_token}`);
|
|
23
|
-
if (!data.ok) {
|
|
24
|
-
throw new Error("Unable to refresh token");
|
|
25
|
-
}
|
|
26
|
-
const refreshedCreds = (await data.json());
|
|
27
|
-
credentials.aws = refreshedCreds.aws;
|
|
28
|
-
credentials.dana = {
|
|
29
|
-
...refreshedCreds.token,
|
|
30
|
-
refresh_token: credentials.dana.refresh_token,
|
|
31
|
-
};
|
|
32
|
-
CredentialsHelper.store(credentials);
|
|
33
|
-
}
|
|
34
|
-
prompts.log.info(`Retrieved credentials for ${org} from local cache`);
|
|
35
|
-
await codeartifactLogin(org, credentials.aws);
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
catch (error) {
|
|
39
|
-
// Log message and start nominal login process
|
|
40
|
-
prompts.log.error(error.message);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
prompts.intro(`Login to ${org}...`);
|
|
10
|
+
const login = async ({ org }) => {
|
|
11
|
+
const credentials = CredentialsHelper.get(org);
|
|
44
12
|
try {
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const token = JSON.parse(req.query.token);
|
|
55
|
-
const awsCredentials = JSON.parse(req.query.aws);
|
|
56
|
-
CredentialsHelper.store({ aws: awsCredentials, dana: token, org });
|
|
57
|
-
// Login to codeartifact repository
|
|
58
|
-
await codeartifactLogin(org, awsCredentials);
|
|
59
|
-
prompts.outro(colors.green("✓") + ` Login successfull`);
|
|
60
|
-
res.send("Login successful! You can close this window.");
|
|
61
|
-
}
|
|
62
|
-
catch (err) {
|
|
63
|
-
console.error(err);
|
|
64
|
-
res.send("Login failed. Check the CLI for details.");
|
|
65
|
-
handleError(err);
|
|
66
|
-
}
|
|
67
|
-
finally {
|
|
68
|
-
server.close();
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
await open(`${apiUrl}/login?port=${port}`);
|
|
13
|
+
prompts.intro(`Login to organization ${credentials.org} ...`);
|
|
14
|
+
const validCredentials = await AuthenticationManager.login(credentials.org);
|
|
15
|
+
prompts.outro(colors.green("✓") + ` Login successful`);
|
|
16
|
+
const npmToken = await AuthenticationManager.loginNPM(credentials.org, validCredentials.aws);
|
|
17
|
+
let stepText = "Successfully logged in to npm repository.";
|
|
18
|
+
if (npmToken.expiration) {
|
|
19
|
+
stepText += `\nLogin expires in 12 hours at: ${npmToken.expiration.toLocaleString()}`;
|
|
20
|
+
}
|
|
21
|
+
prompts.log.step(stepText);
|
|
72
22
|
}
|
|
73
23
|
catch (error) {
|
|
74
|
-
console.error(error);
|
|
75
24
|
handleError(error);
|
|
76
25
|
}
|
|
77
26
|
};
|
|
78
|
-
const handleError = (error) => {
|
|
79
|
-
const message = error instanceof Error ? error.message : error;
|
|
80
|
-
prompts.outro(colors.red(`An issue occurred :` + message));
|
|
81
|
-
process.exit(LOGIN_ERROR);
|
|
82
|
-
};
|
|
83
|
-
const codeartifactLogin = async (organization, credentials) => {
|
|
84
|
-
// Create CodeArtifact client with credentials
|
|
85
|
-
const client = createCodeArtifactClient(credentials);
|
|
86
|
-
// Get authorization token
|
|
87
|
-
const tokenCommand = new GetAuthorizationTokenCommand({
|
|
88
|
-
domain: DOMAIN,
|
|
89
|
-
domainOwner: DOMAIN_OWNER,
|
|
90
|
-
});
|
|
91
|
-
const { authorizationToken, expiration } = await client.send(tokenCommand);
|
|
92
|
-
if (!authorizationToken) {
|
|
93
|
-
throw new Error("Authorization token not found");
|
|
94
|
-
}
|
|
95
|
-
// Get repository endpoint
|
|
96
|
-
const repositoryEndpoint = await getRepositoryEndpoint({ organization, credentials, client, format: "npm" });
|
|
97
|
-
// Configure npm with the repository and token
|
|
98
|
-
execSync(`npm config set @dana:registry=${repositoryEndpoint}`);
|
|
99
|
-
execSync(`npm config set //${repositoryEndpoint.replace(/^https?:\/\//, "")}:_authToken=${authorizationToken}`);
|
|
100
|
-
const expiresAt = expiration ? new Date(expiration).toLocaleString() : "unknown";
|
|
101
|
-
prompts.log.step(`Successfully configured npm to use AWS CodeArtifact repository ${repositoryEndpoint}. \nLogin expires in 12 hours at: ${expiresAt}`);
|
|
102
|
-
};
|
|
103
27
|
export default login;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as prompts from "@clack/prompts";
|
|
2
|
+
import colors from "picocolors";
|
|
3
|
+
import { CredentialsHelper } from "../helper/CredentialsHelper.js";
|
|
4
|
+
import { AuthenticationManager } from "../AuthenticationManager.js";
|
|
5
|
+
import { handleError } from "../helper/CommandHelper.js";
|
|
6
|
+
/*
|
|
7
|
+
Logout from DANA backend
|
|
8
|
+
*/
|
|
9
|
+
const logout = async ({ org }) => {
|
|
10
|
+
const credentials = CredentialsHelper.get(org);
|
|
11
|
+
try {
|
|
12
|
+
prompts.intro(`Logout from ${credentials.org}...`);
|
|
13
|
+
await AuthenticationManager.logout(credentials.org, credentials.dana);
|
|
14
|
+
prompts.outro(colors.green("✓") + ` Logout successful. You are now being logged out in your browser.`);
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
handleError(error);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
export default logout;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const handleError: (error: unknown) => void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as prompts from "@clack/prompts";
|
|
2
|
+
import colors from "picocolors";
|
|
3
|
+
import translation from "../../../common/translation/translation.js";
|
|
4
|
+
import { LOGIN_ERROR } from "../../../common/const/exitCodeConst.js";
|
|
5
|
+
export const handleError = (error) => {
|
|
6
|
+
prompts.outro(colors.red(error.message ?? translation["error.common.start.message"]));
|
|
7
|
+
process.exit(LOGIN_ERROR);
|
|
8
|
+
};
|
|
@@ -8,20 +8,33 @@ export interface AwsCredentials {
|
|
|
8
8
|
export interface DanaToken {
|
|
9
9
|
id_token: string;
|
|
10
10
|
access_token: string;
|
|
11
|
-
refresh_token
|
|
11
|
+
refresh_token: string;
|
|
12
12
|
expires_in: number;
|
|
13
13
|
token_type: string;
|
|
14
14
|
}
|
|
15
|
+
export interface OrgCredentials {
|
|
16
|
+
aws: AwsCredentials;
|
|
17
|
+
dana: DanaToken;
|
|
18
|
+
}
|
|
19
|
+
export interface DanaConfig {
|
|
20
|
+
lastUsedOrg: string;
|
|
21
|
+
version: number;
|
|
22
|
+
credentials: Record<string, OrgCredentials>;
|
|
23
|
+
}
|
|
24
|
+
export declare const CURRENT_DANA_JSON_VERSION = 2;
|
|
15
25
|
export declare class CredentialsHelper {
|
|
16
26
|
static readonly filePath: string;
|
|
27
|
+
static getConfig(): DanaConfig | null;
|
|
28
|
+
private static migrateConfig;
|
|
17
29
|
static store(credentials: {
|
|
18
30
|
aws: AwsCredentials;
|
|
19
31
|
dana: DanaToken;
|
|
20
32
|
org: string;
|
|
21
33
|
}): void;
|
|
22
|
-
static get(): {
|
|
23
|
-
aws
|
|
24
|
-
dana
|
|
34
|
+
static get(org?: string): {
|
|
35
|
+
aws?: AwsCredentials;
|
|
36
|
+
dana?: DanaToken;
|
|
25
37
|
org: string;
|
|
26
|
-
}
|
|
38
|
+
};
|
|
39
|
+
static delete(org: string): void;
|
|
27
40
|
}
|
|
@@ -1,15 +1,65 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { DEFAULT_ORG } from "../authentConst.js";
|
|
5
|
+
export const CURRENT_DANA_JSON_VERSION = 2;
|
|
4
6
|
export class CredentialsHelper {
|
|
5
7
|
static filePath = path.join(homedir(), ".dana.json");
|
|
6
|
-
static
|
|
7
|
-
writeFileSync(this.filePath, JSON.stringify(credentials, null, 4));
|
|
8
|
-
}
|
|
9
|
-
static get() {
|
|
8
|
+
static getConfig() {
|
|
10
9
|
if (!existsSync(this.filePath)) {
|
|
11
10
|
return null;
|
|
12
11
|
}
|
|
13
|
-
|
|
12
|
+
let config = JSON.parse(readFileSync(this.filePath, { encoding: "utf-8" }));
|
|
13
|
+
const configVersion = config.version ?? 1;
|
|
14
|
+
if (configVersion != CURRENT_DANA_JSON_VERSION) {
|
|
15
|
+
config = CredentialsHelper.migrateConfig(config, configVersion);
|
|
16
|
+
writeFileSync(this.filePath, JSON.stringify(config, null, 4));
|
|
17
|
+
}
|
|
18
|
+
return config;
|
|
19
|
+
}
|
|
20
|
+
static migrateConfig(config, from) {
|
|
21
|
+
if (from === 1) {
|
|
22
|
+
const v1 = config;
|
|
23
|
+
return {
|
|
24
|
+
lastUsedOrg: v1.org,
|
|
25
|
+
credentials: {
|
|
26
|
+
[v1.org]: {
|
|
27
|
+
dana: v1.dana,
|
|
28
|
+
aws: v1.aws,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
version: CURRENT_DANA_JSON_VERSION,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return config;
|
|
35
|
+
}
|
|
36
|
+
static store(credentials) {
|
|
37
|
+
let config = this.getConfig();
|
|
38
|
+
config ??= { lastUsedOrg: credentials.org, credentials: {}, version: CURRENT_DANA_JSON_VERSION };
|
|
39
|
+
config.credentials ??= {};
|
|
40
|
+
config.lastUsedOrg = credentials.org;
|
|
41
|
+
config.credentials[credentials.org] = { aws: credentials.aws, dana: credentials.dana };
|
|
42
|
+
writeFileSync(this.filePath, JSON.stringify(config, null, 4));
|
|
43
|
+
}
|
|
44
|
+
static get(org) {
|
|
45
|
+
const config = this.getConfig();
|
|
46
|
+
const organization = org ?? config?.lastUsedOrg ?? DEFAULT_ORG;
|
|
47
|
+
const creds = {
|
|
48
|
+
org: organization,
|
|
49
|
+
};
|
|
50
|
+
if (config?.credentials?.[organization]?.aws) {
|
|
51
|
+
creds.aws = config?.credentials[organization]?.aws;
|
|
52
|
+
}
|
|
53
|
+
if (config?.credentials?.[organization]?.dana) {
|
|
54
|
+
creds.dana = config?.credentials[organization]?.dana;
|
|
55
|
+
}
|
|
56
|
+
return creds;
|
|
57
|
+
}
|
|
58
|
+
static delete(org) {
|
|
59
|
+
const config = this.getConfig();
|
|
60
|
+
if (config) {
|
|
61
|
+
delete config.credentials[org];
|
|
62
|
+
writeFileSync(this.filePath, JSON.stringify(config, null, 4));
|
|
63
|
+
}
|
|
14
64
|
}
|
|
15
65
|
}
|
|
@@ -89,7 +89,6 @@ declare const CreateAppHelper: {
|
|
|
89
89
|
updateProfileJsonWithRenderers(jsonData: Record<string, unknown>, renderers: string[]): object;
|
|
90
90
|
} | {
|
|
91
91
|
new (): {};
|
|
92
|
-
readonly _getAppIcon: () => Promise<string>;
|
|
93
92
|
readonly _askAppId: () => Promise<string>;
|
|
94
93
|
readonly _askAppName: () => Promise<string>;
|
|
95
94
|
readonly _askAppVersion: () => Promise<string>;
|
|
@@ -29,7 +29,7 @@ const BASIC_SETUP = {
|
|
|
29
29
|
[TIZEN]: {
|
|
30
30
|
label: "Samsung",
|
|
31
31
|
package: "@dana/vendor-tizen",
|
|
32
|
-
dependencies: ["@dana/vendor-tizen", "@dana/vendor-shaka"],
|
|
32
|
+
dependencies: ["@dana/vendor-tizen", "@dana/vendor-shaka", "@dana/tools-smarttv-grunt"],
|
|
33
33
|
},
|
|
34
34
|
};
|
|
35
35
|
//Devices that need a subscription to be added in project
|
|
@@ -60,7 +60,7 @@ class CreateFileHelper {
|
|
|
60
60
|
credentials: credentials?.aws,
|
|
61
61
|
format: "maven",
|
|
62
62
|
});
|
|
63
|
-
let gruntOptions = `--appUrl="${registryAccount}" `;
|
|
63
|
+
let gruntOptions = `--appUrl="${registryAccount}" --organization="${credentials.org}" `;
|
|
64
64
|
const optionsToAdd = ["appId", "appName", "appVersion", "appVersionCode", "wtvAndroidVersion"];
|
|
65
65
|
for (const option of optionsToAdd) {
|
|
66
66
|
gruntOptions += `--${option}="${config.androidtv?.device[option]}" `;
|
|
@@ -11,6 +11,7 @@ declare class InstallHelper {
|
|
|
11
11
|
}) => Promise<string>;
|
|
12
12
|
private static getDependenciesList;
|
|
13
13
|
private static readonly installSingleDependency;
|
|
14
|
+
private static readonly updateSemver;
|
|
14
15
|
/**
|
|
15
16
|
* Get a list of all dependencies needed by the different devices chosen by user
|
|
16
17
|
*/
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
import { exec } from "node:child_process";
|
|
13
13
|
import { BASIC_DEPENDENCIES, PLATFORM_CONFIG } from "../const/deviceConst.js";
|
|
14
14
|
import translation from "../translation/translation.js";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
import fs from "node:fs";
|
|
15
17
|
class InstallHelper {
|
|
16
18
|
/**
|
|
17
19
|
* Install dependencies with npm
|
|
@@ -22,9 +24,9 @@ class InstallHelper {
|
|
|
22
24
|
return new Promise((resolve, reject) => {
|
|
23
25
|
exec(`npm i --prefix ${directory} --silent`, {}, (async () => {
|
|
24
26
|
try {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
const dependenciesString = devDependencies.join(" ").trim();
|
|
28
|
+
await InstallHelper.installSingleDependency(dependenciesString, directory);
|
|
29
|
+
InstallHelper.updateSemver(directory);
|
|
28
30
|
resolve("Dependencies updated");
|
|
29
31
|
}
|
|
30
32
|
catch (error) {
|
|
@@ -53,6 +55,16 @@ class InstallHelper {
|
|
|
53
55
|
});
|
|
54
56
|
});
|
|
55
57
|
};
|
|
58
|
+
static updateSemver = (directory) => {
|
|
59
|
+
const filePath = path.join(directory, "package.json");
|
|
60
|
+
const packageJson = JSON.parse(fs.readFileSync(filePath).toString());
|
|
61
|
+
packageJson.devDependencies = Object.entries(packageJson.devDependencies).reduce((acc, [key, value]) => {
|
|
62
|
+
acc[key] =
|
|
63
|
+
key.includes("@dana") || key.includes("@wiztivi") ? value.replace(/(\d+\.\d+\.)\d$/, "$1x") : value;
|
|
64
|
+
return acc;
|
|
65
|
+
}, {});
|
|
66
|
+
fs.writeFileSync(filePath, JSON.stringify(packageJson, null, 4));
|
|
67
|
+
};
|
|
56
68
|
/**
|
|
57
69
|
* Get a list of all dependencies needed by the different devices chosen by user
|
|
58
70
|
*/
|
|
@@ -16,6 +16,7 @@ import { templateGenerator } from "./handlebarsHelper.js";
|
|
|
16
16
|
import { CredentialsHelper } from "../../commands/authentication/helper/CredentialsHelper.js";
|
|
17
17
|
import { getRepositoryEndpoint } from "../../commands/authentication/helper/CodeArtifactHelper.js";
|
|
18
18
|
import { REGISTRY_KEY } from "../../commands/createApp/const/setupConst.js";
|
|
19
|
+
import { formatToCamelCase } from "./stringHelper.js";
|
|
19
20
|
class UpdateFileHelper {
|
|
20
21
|
/**
|
|
21
22
|
* Update app.Config files with mandatory Data
|
|
@@ -54,7 +55,9 @@ class UpdateFileHelper {
|
|
|
54
55
|
const filePath = path.join(directory, "package.json");
|
|
55
56
|
const packageJson = JSON.parse(fs.readFileSync(filePath).toString());
|
|
56
57
|
if (name) {
|
|
57
|
-
|
|
58
|
+
//https://docs.npmjs.com/cli/v10/configuring-npm/package-json?v=true
|
|
59
|
+
const unsafeCharRegex = /[^A-Za-z0-9._-]/g;
|
|
60
|
+
packageJson.name = name.replaceAll(unsafeCharRegex, "").toLowerCase();
|
|
58
61
|
}
|
|
59
62
|
for (const device of selectedDevices) {
|
|
60
63
|
const deviceConfig = config[device];
|
|
@@ -87,7 +90,7 @@ class UpdateFileHelper {
|
|
|
87
90
|
};
|
|
88
91
|
static applyTemplatesToFiles = function ({ directory, name, }) {
|
|
89
92
|
const routesFilePath = path.join(directory, "scripts", "app");
|
|
90
|
-
const appName = `${
|
|
93
|
+
const appName = `${formatToCamelCase(name)}`;
|
|
91
94
|
const filesToUpdate = [
|
|
92
95
|
{
|
|
93
96
|
fromPath: path.join(routesFilePath, "TemplateAppRoutes.js.hbs"),
|
|
@@ -117,7 +120,12 @@ class UpdateFileHelper {
|
|
|
117
120
|
return Promise.resolve("Files templated");
|
|
118
121
|
};
|
|
119
122
|
static getConfigFileOutput = function (directory) {
|
|
120
|
-
const configFiles = [
|
|
123
|
+
const configFiles = [
|
|
124
|
+
"gitignoreTemplate.hbs",
|
|
125
|
+
"editorconfigTemplate.hbs",
|
|
126
|
+
"eslintrc.jsonTemplate.hbs",
|
|
127
|
+
"nvmrcTemplate.hbs",
|
|
128
|
+
];
|
|
121
129
|
const filesToUpdate = [];
|
|
122
130
|
for (const configFile of configFiles) {
|
|
123
131
|
filesToUpdate.push({
|
|
@@ -44,7 +44,7 @@ class UserInputGetter {
|
|
|
44
44
|
return UserInputGetter.formatAppName(name);
|
|
45
45
|
}
|
|
46
46
|
static formatAppName(input) {
|
|
47
|
-
const separatorRegex = /[
|
|
47
|
+
const separatorRegex = /[ /]+/;
|
|
48
48
|
return input
|
|
49
49
|
.trim()
|
|
50
50
|
.split(separatorRegex)
|
|
@@ -60,6 +60,8 @@ class UserInputGetter {
|
|
|
60
60
|
static getAvailableDevices() {
|
|
61
61
|
const availableDevices = [];
|
|
62
62
|
const unavailableDevices = [];
|
|
63
|
+
const spinner = prompts.spinner();
|
|
64
|
+
spinner.start();
|
|
63
65
|
for (const [key, value] of Object.entries(EXTENDED_SETUP)) {
|
|
64
66
|
try {
|
|
65
67
|
execSync(`npm view ${value.package} --silent`, { encoding: "utf-8" });
|
|
@@ -69,6 +71,7 @@ class UserInputGetter {
|
|
|
69
71
|
unavailableDevices.push(EXTENDED_SETUP[key].label);
|
|
70
72
|
}
|
|
71
73
|
}
|
|
74
|
+
spinner.stop("Available devices checked");
|
|
72
75
|
return Promise.resolve({ availableDevices, unavailableDevices });
|
|
73
76
|
}
|
|
74
77
|
/**
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import { OptionList } from "../types/helperTypes.js";
|
|
2
2
|
export declare const capitalizeFirstLetter: (input: string) => string;
|
|
3
3
|
export declare const optionsListString: (input: OptionList) => string;
|
|
4
|
+
/**
|
|
5
|
+
* Remove separator characters from string and convert it to camelCase
|
|
6
|
+
*/
|
|
7
|
+
export declare const formatToCamelCase: (input: string) => string;
|
|
8
|
+
export declare const formatWordToCamelCase: (input: string) => string;
|
|
@@ -4,3 +4,15 @@ export const capitalizeFirstLetter = (input) => {
|
|
|
4
4
|
export const optionsListString = (input) => {
|
|
5
5
|
return input.map((option) => option.command).join(", ");
|
|
6
6
|
};
|
|
7
|
+
/**
|
|
8
|
+
* Remove separator characters from string and convert it to camelCase
|
|
9
|
+
*/
|
|
10
|
+
export const formatToCamelCase = (input) => {
|
|
11
|
+
const separatorRegex = /[./_\-\\ ]/g;
|
|
12
|
+
return input
|
|
13
|
+
.trim()
|
|
14
|
+
.split(separatorRegex)
|
|
15
|
+
.map((el, index) => (index === 0 ? el.toLowerCase() : formatWordToCamelCase(el)))
|
|
16
|
+
.join("");
|
|
17
|
+
};
|
|
18
|
+
export const formatWordToCamelCase = (input) => `${input[0].toUpperCase()}${input.substring(1).toLowerCase()}`;
|
|
@@ -22,8 +22,10 @@
|
|
|
22
22
|
"helper.git.status.error": "Git status is not clean or an error occurred. Try to commit your change.",
|
|
23
23
|
"command.auth.description": "Authenticate to Dana framework",
|
|
24
24
|
"command.auth.login.description": "Login to Dana",
|
|
25
|
-
"command.auth.
|
|
25
|
+
"command.auth.logout.description": "Logout from Dana",
|
|
26
|
+
"command.auth.login.option.org": "Organization to login/logout",
|
|
26
27
|
"command.auth.status.description": "Get login status",
|
|
28
|
+
"command.auth.get-packages-token.description": "Get token for packages repository",
|
|
27
29
|
"command.scrollView.description": "Add a scrollView of rails",
|
|
28
30
|
"command.scrollView.option.itemView": "Item to be used in the scrollView. Default: pre-made rail",
|
|
29
31
|
"command.scrollView.option.itemMargin": "Margin between items. Default: 550",
|
|
@@ -56,7 +58,7 @@
|
|
|
56
58
|
"command.completion.argument": "Shell. Bash or zsh",
|
|
57
59
|
"command.completion.success": "Completion installed to ",
|
|
58
60
|
"login.info.token_expired": "Your token has expired.",
|
|
59
|
-
"login.info.please_login": "Please run dana auth login command",
|
|
61
|
+
"login.info.please_login": "Please run 'dana auth login' command",
|
|
60
62
|
"login.error.not_logged": "You're not logged in.",
|
|
61
63
|
"login.info.logged": "You're currently logged in to Dana"
|
|
62
64
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wiztivi/dana-cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "Dana create app CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": "./dist/index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@aws-sdk/client-codeartifact": "^3.859.0",
|
|
30
30
|
"@clack/prompts": "0.10.0",
|
|
31
|
-
"@wiztivi/dana-templates": "^0.0.
|
|
31
|
+
"@wiztivi/dana-templates": "^0.0.10",
|
|
32
32
|
"child_process": "1.0.x",
|
|
33
33
|
"command-exists": "1.2.9",
|
|
34
34
|
"commander": "11.1.x",
|