Skip to content

Commit 02c71c8

Browse files
committed
feat: npm publish --access public
1 parent 4b8e3f3 commit 02c71c8

7 files changed

Lines changed: 265 additions & 0 deletions

File tree

.npmignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# test .npmignore by run "npm pack" before run "npm publish"
2+
vendor
3+
node_modules
4+
node_lambda_layer
5+
.serverless
6+
.env
7+
example
8+
vercel.*
9+
serverless.*
10+
*.zip
11+
*.tgz
12+
*.gz
13+
*bak.js
14+
*BAK.js
15+
test

cloud-config.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import AES from "crypto-js/aes";
2+
import encUtf8 from "crypto-js/enc-utf8";
3+
4+
export interface CloudConfigData {
5+
projectName: string;
6+
groupName: string;
7+
featureKey: string;
8+
value: unknown;
9+
valueType: string;
10+
prodEnabled?: boolean;
11+
devEnabled?: boolean;
12+
valueEncrypted?: boolean;
13+
}
14+
15+
export const CLOUD_CONFIG_DEFAULT_GROUP = "defaultGroup";
16+
export const CLOUD_CONFIG_DEFAULT_PROJECT = "defaultProject";
17+
18+
const couldConfigSecretClient =
19+
process.env.NEXT_PUBLIC_CLOUD_CONFIG_CLIENT_ENCRYPT_SECRET;
20+
21+
const couldConfigSecretServer = process.env.CLOUD_CONFIG_SERVER_ENCRYPT_SECRET;
22+
23+
export const IS_PROD = process.env.NODE_ENV === "production";
24+
25+
export const decryptData = (
26+
data: string,
27+
cryptSecret: string
28+
): string | null => {
29+
const decryptedText = AES.decrypt(data, cryptSecret);
30+
if (!decryptedText) {
31+
return null;
32+
}
33+
return decryptedText.toString(encUtf8);
34+
};
35+
36+
export const parseSingleConfig = (
37+
config: CloudConfigData,
38+
serverSideOnly = false
39+
): CloudConfigData => {
40+
if (!config.valueEncrypted) {
41+
return config;
42+
}
43+
const cryptSecret = serverSideOnly
44+
? couldConfigSecretServer
45+
: couldConfigSecretClient;
46+
if (!cryptSecret) {
47+
// eslint-disable-next-line no-console
48+
console.log(
49+
`Can't decrypt featureKey ${config.featureKey}, Please set ${
50+
serverSideOnly
51+
? "CLOUD_CONFIG_SERVER_ENCRYPT_SECRET"
52+
: "NEXT_PUBLIC_CLOUD_CONFIG_CLIENT_ENCRYPT_SECRET"
53+
} in .env`
54+
);
55+
return config;
56+
}
57+
const decryptedValue = decryptData(config.value as string, cryptSecret);
58+
if (!decryptedValue) {
59+
return config;
60+
}
61+
62+
let newValue;
63+
if (config.valueType === "json") {
64+
try {
65+
newValue = JSON.parse(decryptedValue);
66+
} catch (error) {
67+
// eslint-disable-next-line no-console
68+
console.log("JSON.parse(decryptedValue) error", config.value, error);
69+
}
70+
}
71+
if (config.valueType === "array") {
72+
newValue = decryptedValue.split(",").map((tag) => tag.trim());
73+
}
74+
if (config.valueType === "number") {
75+
newValue = parseFloat(decryptedValue);
76+
}
77+
if (config.valueType === "boolean") {
78+
newValue = Boolean(decryptedValue);
79+
}
80+
81+
const newConfig = {
82+
...config,
83+
value: newValue || decryptedValue,
84+
};
85+
86+
return newConfig;
87+
};
88+
89+
export const parseAllConfigs = (
90+
configs: CloudConfigData[],
91+
serverSideOnly = false
92+
): CloudConfigData[] => {
93+
return configs.map((config) => parseSingleConfig(config, serverSideOnly));
94+
};
95+
96+
interface GetCloudConfigParams {
97+
featureKey: string;
98+
groupName?: string;
99+
projectName?: string;
100+
configs: CloudConfigData[];
101+
}
102+
103+
export const getCloudConfig = <T>({
104+
featureKey,
105+
groupName = CLOUD_CONFIG_DEFAULT_GROUP,
106+
projectName = CLOUD_CONFIG_DEFAULT_PROJECT,
107+
configs,
108+
}: GetCloudConfigParams) => {
109+
const config = configs.find((item) => {
110+
if (item.featureKey !== featureKey) {
111+
return false;
112+
}
113+
if (item.groupName !== groupName) {
114+
return false;
115+
}
116+
if (item.projectName !== projectName) {
117+
return false;
118+
}
119+
return true;
120+
});
121+
if (!config) {
122+
return null;
123+
}
124+
if (IS_PROD && !config.prodEnabled) {
125+
return null;
126+
}
127+
if (!IS_PROD && !config.devEnabled) {
128+
return null;
129+
}
130+
131+
return config.value as T;
132+
};

index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./cloud-config";

package-lock.json

Lines changed: 56 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "cloud-configuration",
3+
"version": "0.1.0",
4+
"description": "This package allows you to use CloudConfig easily.",
5+
"author": "Alex Zeng",
6+
"license": "MIT",
7+
"main": "index.js",
8+
"scripts": {
9+
"test": "echo \"Error: no test specified\" && exit 1"
10+
},
11+
"repository": {
12+
"type": "git",
13+
"url": "git+https://github.com/AlexStack/cloud-config-package.git"
14+
},
15+
"keywords": [],
16+
"bugs": {
17+
"url": "https://github.com/AlexStack/cloud-config-package/issues"
18+
},
19+
"homepage": "https://github.com/AlexStack/cloud-config-package#readme",
20+
"devDependencies": {
21+
"@types/crypto-js": "^4.1.2",
22+
"@types/node": "^20.8.2"
23+
},
24+
"dependencies": {
25+
"crypto-js": "^4.1.1"
26+
}
27+
}

test/test-config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { decryptData } from "cloud-config";
2+
3+
console.log("test-config.ts", decryptData("U2FsdG", "test"));

tsconfig.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"lib": ["dom", "dom.iterable", "esnext"],
5+
"allowJs": true,
6+
"skipLibCheck": true,
7+
"strict": true,
8+
"forceConsistentCasingInFileNames": true,
9+
"noEmit": true,
10+
"esModuleInterop": true,
11+
"module": "esnext",
12+
"moduleResolution": "node",
13+
"resolveJsonModule": true,
14+
"isolatedModules": true,
15+
"jsx": "preserve",
16+
"baseUrl": ".",
17+
"paths": {
18+
"@/*": ["./src/*"],
19+
"~/*": ["./public/*"]
20+
},
21+
"incremental": true,
22+
"plugins": [
23+
{
24+
"name": "next"
25+
}
26+
]
27+
},
28+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
29+
"exclude": ["node_modules"],
30+
"moduleResolution": ["node_modules", ".next", "node"]
31+
}

0 commit comments

Comments
 (0)