@catladder/cli 1.102.0 → 1.104.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/dist/apps/catenv/catenv.d.ts +2 -4
- package/dist/apps/catenv/catenv.js +12 -89
- package/dist/apps/catenv/catenv.js.map +1 -1
- package/dist/apps/catenv/printVariables.d.ts +3 -0
- package/dist/apps/catenv/printVariables.js +111 -0
- package/dist/apps/catenv/printVariables.js.map +1 -0
- package/dist/apps/catenv/types.d.ts +5 -0
- package/dist/apps/catenv/types.js +3 -0
- package/dist/apps/catenv/types.js.map +1 -0
- package/dist/apps/catenv/utils.d.ts +12 -0
- package/dist/apps/catenv/utils.js +108 -0
- package/dist/apps/catenv/utils.js.map +1 -0
- package/dist/apps/catenv/writeDotEnvFiles.d.ts +3 -0
- package/dist/apps/catenv/writeDotEnvFiles.js +93 -0
- package/dist/apps/catenv/writeDotEnvFiles.js.map +1 -0
- package/dist/apps/catenv/writeEnvDTs.d.ts +3 -0
- package/dist/apps/catenv/writeEnvDTs.js +114 -0
- package/dist/apps/catenv/writeEnvDTs.js.map +1 -0
- package/dist/bundles/catenv/index.js +3 -3
- package/dist/bundles/cli/index.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/apps/catenv/catenv.ts +11 -65
- package/src/apps/catenv/printVariables.ts +51 -0
- package/src/apps/catenv/types.ts +6 -0
- package/src/apps/catenv/utils.ts +49 -0
- package/src/apps/catenv/writeDotEnvFiles.ts +45 -0
- package/src/apps/catenv/writeEnvDTs.ts +71 -0
- package/tsconfig.json +1 -1
package/package.json
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"node": ">=12.0.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@catladder/pipeline": "1.
|
|
27
|
+
"@catladder/pipeline": "1.104.0",
|
|
28
28
|
"@kubernetes/client-node": "^0.16.2",
|
|
29
29
|
"@tsconfig/node14": "^1.0.1",
|
|
30
30
|
"@types/common-tags": "^1.8.0",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"typescript": "^4.5.4",
|
|
58
58
|
"vorpal": "^1.12.0"
|
|
59
59
|
},
|
|
60
|
-
"version": "1.
|
|
60
|
+
"version": "1.104.0"
|
|
61
61
|
}
|
|
@@ -1,72 +1,18 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from "
|
|
6
|
-
import { getGitRoot } from "../../utils/projects";
|
|
7
|
-
import { join } from "path";
|
|
8
|
-
const getCurrentComponentName = async (
|
|
9
|
-
components: Record<string, ComponentConfig>
|
|
10
|
-
) => {
|
|
11
|
-
const gitRoot = await getGitRoot();
|
|
12
|
-
const currentDir = process.cwd();
|
|
13
|
-
return Object.keys(components).find((c) =>
|
|
14
|
-
currentDir.startsWith(join(gitRoot, components[c].dir))
|
|
15
|
-
);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const sanitizeEnvVarName = (name: string) => name.replace(/[\s\-.]+/g, "_");
|
|
19
|
-
|
|
20
|
-
const getAllVariablesToPrint = async (
|
|
21
|
-
config: Config,
|
|
22
|
-
choice?: {
|
|
23
|
-
env?: string;
|
|
24
|
-
componentName?: string;
|
|
25
|
-
}
|
|
26
|
-
) => {
|
|
27
|
-
const env = choice?.env ?? "local";
|
|
28
|
-
const { components } = config;
|
|
29
|
-
|
|
30
|
-
const currentComponent =
|
|
31
|
-
choice?.componentName ?? (await getCurrentComponentName(components));
|
|
1
|
+
import { getProjectConfig } from "../../config/getProjectConfig";
|
|
2
|
+
import { printVariables } from "./printVariables";
|
|
3
|
+
import type { Choice } from "./types";
|
|
4
|
+
import { writeDotEnvFiles } from "./writeDotEnvFiles";
|
|
5
|
+
import { writeDTsFiles } from "./writeEnvDTs";
|
|
32
6
|
|
|
33
|
-
|
|
34
|
-
if (currentComponent) {
|
|
35
|
-
variables = await getEnvVarsResolved(null, env, currentComponent);
|
|
36
|
-
} else {
|
|
37
|
-
// when in a monorep and not in a subapp, merge all env vars.
|
|
38
|
-
// this is not 100% correct, but better than not exporting any vars at all
|
|
39
|
-
// so we also add prefixed variants
|
|
40
|
-
variables = await Object.keys(components).reduce(
|
|
41
|
-
async (acc, componentName) => {
|
|
42
|
-
const subappvars = await getEnvVarsResolved(null, env, componentName);
|
|
43
|
-
return {
|
|
44
|
-
...(await acc),
|
|
45
|
-
...subappvars,
|
|
46
|
-
// also add prefixed variants in case
|
|
47
|
-
...Object.fromEntries(
|
|
48
|
-
Object.entries(subappvars).map(([key, value]) => [
|
|
49
|
-
`${sanitizeEnvVarName(componentName.toUpperCase())}_${key}`,
|
|
50
|
-
value,
|
|
51
|
-
])
|
|
52
|
-
),
|
|
53
|
-
};
|
|
54
|
-
},
|
|
55
|
-
{}
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
return variables;
|
|
59
|
-
};
|
|
60
|
-
export default async (choice?: { env?: string; componentName?: string }) => {
|
|
7
|
+
export default async (choice?: Choice) => {
|
|
61
8
|
const config = await getProjectConfig();
|
|
62
9
|
if (!config) {
|
|
63
10
|
return;
|
|
64
11
|
}
|
|
65
|
-
const variables = await getAllVariablesToPrint(config, choice);
|
|
66
12
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
);
|
|
13
|
+
await printVariables(config, choice);
|
|
14
|
+
|
|
15
|
+
await writeDotEnvFiles(config, choice);
|
|
16
|
+
|
|
17
|
+
await writeDTsFiles(config, choice);
|
|
72
18
|
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Config } from "@catladder/pipeline";
|
|
2
|
+
import { getEnvVarsResolved } from "../../config/getProjectConfig";
|
|
3
|
+
import type { Choice, Variables } from "./types";
|
|
4
|
+
import {
|
|
5
|
+
getCurrentComponentAndEnvFromChoice,
|
|
6
|
+
makeKeyValueString,
|
|
7
|
+
sanitizeEnvVarName,
|
|
8
|
+
} from "./utils";
|
|
9
|
+
|
|
10
|
+
const getAllVariablesToPrint = async (config: Config, choice?: Choice) => {
|
|
11
|
+
const { env, currentComponent } = await getCurrentComponentAndEnvFromChoice(
|
|
12
|
+
config,
|
|
13
|
+
choice
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
let variables = {};
|
|
17
|
+
if (currentComponent) {
|
|
18
|
+
variables = await getEnvVarsResolved(null, env, currentComponent);
|
|
19
|
+
} else {
|
|
20
|
+
// when in a monorep and not in a subapp, merge all env vars.
|
|
21
|
+
// this is not 100% correct, but better than not exporting any vars at all
|
|
22
|
+
// so we also add prefixed variants
|
|
23
|
+
variables = await Object.keys(config.components).reduce(
|
|
24
|
+
async (acc, componentName) => {
|
|
25
|
+
const subappvars = await getEnvVarsResolved(null, env, componentName);
|
|
26
|
+
return {
|
|
27
|
+
...(await acc),
|
|
28
|
+
...subappvars,
|
|
29
|
+
// also add prefixed variants in case
|
|
30
|
+
...Object.fromEntries(
|
|
31
|
+
Object.entries(subappvars).map(([key, value]) => [
|
|
32
|
+
`${sanitizeEnvVarName(componentName.toUpperCase())}_${key}`,
|
|
33
|
+
value,
|
|
34
|
+
])
|
|
35
|
+
),
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
{}
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
return variables;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const printVariables = async (config: Config, choice?: Choice) => {
|
|
45
|
+
const variables = await getAllVariablesToPrint(config, choice);
|
|
46
|
+
|
|
47
|
+
console.log(makeExportKeyValuestring(variables));
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const makeExportKeyValuestring = (variables: Variables) =>
|
|
51
|
+
makeKeyValueString(variables, "export ");
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Config } from "@catladder/pipeline";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { getGitRoot } from "../../utils/projects";
|
|
4
|
+
import type { Choice, Variables } from "./types";
|
|
5
|
+
export const getComponentFullPath = (
|
|
6
|
+
gitRoot: string,
|
|
7
|
+
config: Config,
|
|
8
|
+
componentName: string
|
|
9
|
+
) => {
|
|
10
|
+
return join(gitRoot, config.components[componentName].dir);
|
|
11
|
+
};
|
|
12
|
+
const getCurrentComponentName = async (config: Config) => {
|
|
13
|
+
const gitRoot = await getGitRoot();
|
|
14
|
+
const currentDir = process.cwd();
|
|
15
|
+
return Object.keys(config.components).find((c) =>
|
|
16
|
+
currentDir.startsWith(getComponentFullPath(gitRoot, config, c))
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const getCurrentComponentAndEnvFromChoice = async (
|
|
21
|
+
config: Config,
|
|
22
|
+
choice?: Choice
|
|
23
|
+
) => {
|
|
24
|
+
const env = choice?.env ?? "local";
|
|
25
|
+
const currentComponent =
|
|
26
|
+
choice?.componentName ?? (await getCurrentComponentName(config));
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
currentComponent,
|
|
30
|
+
env,
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const makeKeyValueString = (variables: Variables, keyPrefix = "") =>
|
|
35
|
+
Object.entries(variables)
|
|
36
|
+
.map(([key, value]) => `${keyPrefix}${key}='${value}'`)
|
|
37
|
+
.join("\n");
|
|
38
|
+
|
|
39
|
+
export const sanitizeMultiLine = (variables: Variables) => {
|
|
40
|
+
return Object.fromEntries(
|
|
41
|
+
Object.entries(variables).map(([key, value]) => [
|
|
42
|
+
key,
|
|
43
|
+
value.replaceAll("\n", "\\n"),
|
|
44
|
+
])
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const sanitizeEnvVarName = (name: string) =>
|
|
49
|
+
name.replace(/[\s\-.]+/g, "_");
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Config } from "@catladder/pipeline";
|
|
2
|
+
import { writeFile } from "fs-extra";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { getEnvVarsResolved } from "../../config/getProjectConfig";
|
|
5
|
+
import { getGitRoot } from "../../utils/projects";
|
|
6
|
+
import type { Choice } from "./types";
|
|
7
|
+
import {
|
|
8
|
+
getComponentFullPath,
|
|
9
|
+
getCurrentComponentAndEnvFromChoice,
|
|
10
|
+
makeKeyValueString,
|
|
11
|
+
sanitizeMultiLine,
|
|
12
|
+
} from "./utils";
|
|
13
|
+
|
|
14
|
+
export const writeDotEnvFiles = async (config: Config, choice?: Choice) => {
|
|
15
|
+
const { env, currentComponent } = await getCurrentComponentAndEnvFromChoice(
|
|
16
|
+
config,
|
|
17
|
+
choice
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
// whether to print .dotenv is currentl configure on the "local" part of the env
|
|
21
|
+
|
|
22
|
+
const componentsWithEnabledDotEnvWrite = Object.entries(config.components)
|
|
23
|
+
.filter(([, component]) => component?.dotEnv)
|
|
24
|
+
.map(([componentName]) => componentName);
|
|
25
|
+
|
|
26
|
+
const componentsToActuallyWriteDotEnvNow = currentComponent
|
|
27
|
+
? componentsWithEnabledDotEnvWrite.includes(currentComponent)
|
|
28
|
+
? [currentComponent]
|
|
29
|
+
: []
|
|
30
|
+
: componentsWithEnabledDotEnvWrite;
|
|
31
|
+
const gitRoot = await getGitRoot();
|
|
32
|
+
|
|
33
|
+
for (const componentName of componentsToActuallyWriteDotEnvNow) {
|
|
34
|
+
const variables = await getEnvVarsResolved(null, env, componentName);
|
|
35
|
+
const componentDir = getComponentFullPath(gitRoot, config, componentName);
|
|
36
|
+
const filePath = join(componentDir, ".env");
|
|
37
|
+
// many .dotenv don't like multiline values, so we sanitize them here
|
|
38
|
+
const variablesSanitized = sanitizeMultiLine(variables);
|
|
39
|
+
await writeFile(
|
|
40
|
+
filePath,
|
|
41
|
+
"# automatically created by catladder. Do not modify!\n\n" +
|
|
42
|
+
makeKeyValueString(variablesSanitized)
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { Config } from "@catladder/pipeline";
|
|
2
|
+
import { writeFile } from "fs-extra";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { getEnvironment } from "../../config/getProjectConfig";
|
|
5
|
+
import { getGitRoot } from "../../utils/projects";
|
|
6
|
+
import type { Choice } from "./types";
|
|
7
|
+
import {
|
|
8
|
+
getComponentFullPath,
|
|
9
|
+
getCurrentComponentAndEnvFromChoice,
|
|
10
|
+
} from "./utils";
|
|
11
|
+
|
|
12
|
+
export const writeDTsFiles = async (config: Config, choice?: Choice) => {
|
|
13
|
+
const { env, currentComponent } = await getCurrentComponentAndEnvFromChoice(
|
|
14
|
+
config,
|
|
15
|
+
choice
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
const componentsWithEnabledEnvDTsWrite = Object.entries(config.components)
|
|
19
|
+
.filter(([, component]) => component?.envDTs)
|
|
20
|
+
.map(([componentName]) => componentName);
|
|
21
|
+
|
|
22
|
+
const componentsToActuallyWriteDotEnvNow = currentComponent
|
|
23
|
+
? componentsWithEnabledEnvDTsWrite.includes(currentComponent)
|
|
24
|
+
? [currentComponent]
|
|
25
|
+
: []
|
|
26
|
+
: componentsWithEnabledEnvDTsWrite;
|
|
27
|
+
const gitRoot = await getGitRoot();
|
|
28
|
+
|
|
29
|
+
for (const componentName of componentsToActuallyWriteDotEnvNow) {
|
|
30
|
+
const envNames = await getEnvsForDTs(env, componentName);
|
|
31
|
+
const envDTsContent = createEnvDTsContent(envNames);
|
|
32
|
+
|
|
33
|
+
const componentDir = getComponentFullPath(gitRoot, config, componentName);
|
|
34
|
+
const filePath = join(componentDir, "env.d.ts");
|
|
35
|
+
await writeFile(filePath, envDTsContent);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
async function getEnvsForDTs(
|
|
40
|
+
env: string,
|
|
41
|
+
componentName: string
|
|
42
|
+
): Promise<string[]> {
|
|
43
|
+
const environment = await getEnvironment(env, componentName);
|
|
44
|
+
const allEnvKeys = Object.keys(environment.envVars);
|
|
45
|
+
const hiddenEnvKeys = new Set(
|
|
46
|
+
environment.secretEnvVarKeys
|
|
47
|
+
.filter((s) => s.hidden)
|
|
48
|
+
.map((s) => s.key)
|
|
49
|
+
.concat(["_ALL_ENV_VAR_KEYS"])
|
|
50
|
+
);
|
|
51
|
+
const dTsEnvKeys = allEnvKeys.filter((k) => !hiddenEnvKeys.has(k));
|
|
52
|
+
|
|
53
|
+
return dTsEnvKeys;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function createEnvDTsContent(envNames: string[]) {
|
|
57
|
+
return `/* tslint:disable prettier/prettier */
|
|
58
|
+
/* eslint-disable prettier/prettier */
|
|
59
|
+
/* prettier-ignore */
|
|
60
|
+
// automatically generated by catladder. Do not modify!
|
|
61
|
+
export {}
|
|
62
|
+
|
|
63
|
+
declare global {
|
|
64
|
+
namespace NodeJS {
|
|
65
|
+
interface ProcessEnv {
|
|
66
|
+
${envNames.map((name) => ` ${name}: string`).join("\n")}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
}
|