tambahan
This commit is contained in:
34
.gitignore
vendored
Normal file
34
.gitignore
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# dependencies (bun install)
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# output
|
||||||
|
out
|
||||||
|
dist
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# code coverage
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# logs
|
||||||
|
logs
|
||||||
|
_.log
|
||||||
|
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# caches
|
||||||
|
.eslintcache
|
||||||
|
.cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# IntelliJ based IDEs
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Finder (MacOS) folder config
|
||||||
|
.DS_Store
|
||||||
32
.npmignore
Normal file
32
.npmignore
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Node/Bun modules
|
||||||
|
node_modules
|
||||||
|
bun.lockb
|
||||||
|
|
||||||
|
# Git & metadata
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.npmignore
|
||||||
|
|
||||||
|
# Config & tools
|
||||||
|
tsconfig.json
|
||||||
|
bunfig.toml
|
||||||
|
.eslintrc*
|
||||||
|
.prettierrc*
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Tests & examples
|
||||||
|
test
|
||||||
|
tests
|
||||||
|
__tests__
|
||||||
|
coverage
|
||||||
|
examples
|
||||||
|
demo
|
||||||
|
|
||||||
|
# Cache / temp
|
||||||
|
*.log
|
||||||
|
*.DS_Store
|
||||||
|
|
||||||
|
# Local env
|
||||||
|
.env
|
||||||
|
.env.*.local
|
||||||
15
README.md
Normal file
15
README.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# g3n
|
||||||
|
|
||||||
|
To install dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun install
|
||||||
|
```
|
||||||
|
|
||||||
|
To run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun run index.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
This project was created using `bun init` in bun v1.2.18. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
|
||||||
35
bin/g3n.ts
Executable file
35
bin/g3n.ts
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env bun
|
||||||
|
import minimist from "minimist";
|
||||||
|
import path from "path";
|
||||||
|
import { generateEnvTypes } from "../generate/env.generate.js";
|
||||||
|
|
||||||
|
const args = minimist(process.argv.slice(2));
|
||||||
|
|
||||||
|
const help = `
|
||||||
|
g3n [command] [options]
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
env Generate env.d.ts from .env file
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--env Path ke file .env (default: .env)
|
||||||
|
--out Path file output (default: types/env.d.ts)
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
g3n env --env .env.local --out src/types/env.d.ts
|
||||||
|
`;
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const cmd = args._[0];
|
||||||
|
|
||||||
|
if (cmd === "env") {
|
||||||
|
generateEnvTypes({
|
||||||
|
envFilePath: args.env,
|
||||||
|
outputDir: args.out ? path.dirname(args.out) : undefined,
|
||||||
|
outputFileName: args.out ? path.basename(args.out) : undefined,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(help);
|
||||||
|
})();
|
||||||
40
bun.lock
Normal file
40
bun.lock
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"workspaces": {
|
||||||
|
"": {
|
||||||
|
"name": "g3n",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/minimist": "^1.2.5",
|
||||||
|
"dotenv": "^17.2.1",
|
||||||
|
"minimist": "^1.2.8",
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/bun": "latest",
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"packages": {
|
||||||
|
"@types/bun": ["@types/bun@1.2.20", "", { "dependencies": { "bun-types": "1.2.20" } }, "sha512-dX3RGzQ8+KgmMw7CsW4xT5ITBSCrSbfHc36SNT31EOUg/LA9JWq0VDdEXDRSe1InVWpd2yLUM1FUF/kEOyTzYA=="],
|
||||||
|
|
||||||
|
"@types/minimist": ["@types/minimist@1.2.5", "", {}, "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag=="],
|
||||||
|
|
||||||
|
"@types/node": ["@types/node@24.3.0", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow=="],
|
||||||
|
|
||||||
|
"@types/react": ["@types/react@19.1.10", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg=="],
|
||||||
|
|
||||||
|
"bun-types": ["bun-types@1.2.20", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-pxTnQYOrKvdOwyiyd/7sMt9yFOenN004Y6O4lCcCUoKVej48FS5cvTw9geRaEcB9TsDZaJKAxPTVvi8tFsVuXA=="],
|
||||||
|
|
||||||
|
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||||
|
|
||||||
|
"dotenv": ["dotenv@17.2.1", "", {}, "sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ=="],
|
||||||
|
|
||||||
|
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
||||||
|
|
||||||
|
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
||||||
|
|
||||||
|
"undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="],
|
||||||
|
}
|
||||||
|
}
|
||||||
48
generate/env.generate.ts
Normal file
48
generate/env.generate.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import * as fs from "fs";
|
||||||
|
import * as path from "path";
|
||||||
|
import * as dotenv from "dotenv";
|
||||||
|
|
||||||
|
interface GenerateEnvTypesOptions {
|
||||||
|
envFilePath?: string;
|
||||||
|
outputDir?: string;
|
||||||
|
outputFileName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateEnvTypes(options: GenerateEnvTypesOptions = {}) {
|
||||||
|
const {
|
||||||
|
envFilePath = path.resolve(process.cwd(), ".env"),
|
||||||
|
outputDir = path.resolve(process.cwd(), "types"),
|
||||||
|
outputFileName = "env.d.ts",
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
const outputFile = path.join(outputDir, outputFileName);
|
||||||
|
|
||||||
|
// 1. Baca .env
|
||||||
|
if (!fs.existsSync(envFilePath)) {
|
||||||
|
console.warn(`⚠️ .env file not found at: ${envFilePath}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const envContent = fs.readFileSync(envFilePath, "utf-8");
|
||||||
|
const parsed = dotenv.parse(envContent);
|
||||||
|
|
||||||
|
// 2. Generate TypeScript declare
|
||||||
|
const lines = Object.keys(parsed).map((key) => ` ${key}?: string;`);
|
||||||
|
|
||||||
|
const fileContent = `declare namespace NodeJS {
|
||||||
|
interface ProcessEnv {
|
||||||
|
${lines.join("\n")}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
// 3. Buat folder kalau belum ada
|
||||||
|
if (!fs.existsSync(outputDir)) {
|
||||||
|
fs.mkdirSync(outputDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Tulis file
|
||||||
|
fs.writeFileSync(outputFile, fileContent, "utf-8");
|
||||||
|
|
||||||
|
console.log(`✅ Env types generated at: ${outputFile}`);
|
||||||
|
}
|
||||||
35
index.ts
Executable file
35
index.ts
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env bun
|
||||||
|
import minimist from "minimist";
|
||||||
|
import { generateEnvTypes } from "./generate/env.generate.js";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
const args = minimist(process.argv.slice(2));
|
||||||
|
|
||||||
|
const help = `
|
||||||
|
g3n [command] [options]
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
env Generate env.d.ts from .env file
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--env Path ke file .env (default: .env)
|
||||||
|
--out Path file output (default: types/env.d.ts)
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
g3n env --env .env.local --out src/types/env.d.ts
|
||||||
|
`;
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const cmd = args._[0];
|
||||||
|
|
||||||
|
if (cmd === "env") {
|
||||||
|
generateEnvTypes({
|
||||||
|
envFilePath: args.env,
|
||||||
|
outputDir: args.out ? path.dirname(args.out) : undefined,
|
||||||
|
outputFileName: args.out ? path.basename(args.out) : undefined,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(help);
|
||||||
|
})();
|
||||||
16
package.json
Normal file
16
package.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "g3n",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"bin": {
|
||||||
|
"g3n": "./bin/g3n.ts"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/minimist": "^1.2.5",
|
||||||
|
"dotenv": "^17.2.1",
|
||||||
|
"minimist": "^1.2.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
29
tsconfig.json
Normal file
29
tsconfig.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
// Environment setup & latest features
|
||||||
|
"lib": ["ESNext"],
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "Preserve",
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"allowJs": true,
|
||||||
|
|
||||||
|
// Bundler mode
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
// Best practices
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
|
||||||
|
// Some stricter flags (disabled by default)
|
||||||
|
"noUnusedLocals": false,
|
||||||
|
"noUnusedParameters": false,
|
||||||
|
"noPropertyAccessFromIndexSignature": false
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user