@settlemint/btp-sdk-cli
Advanced tools
Comparing version
#!/usr/bin/env node | ||
import { program, Command } from '@commander-js/extra-typings'; | ||
import 'reflect-metadata'; | ||
import w from 'boxen'; | ||
import { blue, green, yellow, red } from 'yoctocolors'; | ||
import { writeFileSync, existsSync } from 'node:fs'; | ||
import c from 'node:path'; | ||
import { cancel, intro, outro, spinner, password, isCancel, text } from '@clack/prompts'; | ||
import { Command } from '@commander-js/extra-typings'; | ||
import dotenv from 'dotenv'; | ||
import { magentaBright, inverse, greenBright, redBright } from 'yoctocolors'; | ||
import { writeFileSync, readFileSync, existsSync } from 'node:fs'; | ||
import path from 'node:path'; | ||
import { cosmiconfig } from 'cosmiconfig'; | ||
import { merge } from 'ts-deepmerge'; | ||
import { z } from 'zod'; | ||
import { input, password } from '@inquirer/prompts'; | ||
function s(e,r="info",t=!0){let n={info:blue,success:green,warning:yellow,error:red},i={info:"blue",success:"green",warning:"yellow",error:"red"},l={info:"\u2139\uFE0F",success:"\u2705",warning:"\u26A0\uFE0F",error:"\u274C"},a=n[r](`${l[r]} ${e.replace(/\s+/g," ").trim()}`),o=w(a,{padding:1,margin:1,borderStyle:"round",borderColor:i[r]});return t&&(r==="error"?console.error(o):console.log(o)),o}var p=z.object({pat:z.string(),instance:z.string()});async function E(){let r=await cosmiconfig("btp").search();if(r)return p.parse(r.config)}function S(e){let r=e;for(;r!==c.parse(r).root;){if(existsSync(c.join(r,"package.json")))return r;r=c.dirname(r);}throw new Error("Unable to find project root")}async function u(e){let t=merge({pat:"sm_pat_xxxxxxxxxxxxxxxx",instance:"https://console.settlemint.com"},e),n=p.parse(t),i=await E(),l=i?merge(n,i):t,a=p.parse(l),o=S(process.cwd()),v=c.join(o,".btprc.json");return writeFileSync(v,JSON.stringify(a,null,2)),a}async function m(e){let r=process.env.BTP_INSTANCE_URL||e;return d(r)||(r=await input({message:"Enter the URL of your BTP instance",default:"https://console.settlemint.com",validate:t=>L(t)})),r}function d(e){try{return new URL(e??"").protocol==="https:"}catch{return !1}}function L(e){return d(e)?!0:"Invalid BTP instance URL. Please enter a valid HTTPS URL."}async function x(e){let r=process.env.BTP_PAT_TOKEN||e;return h(r)||(r=await password({message:"Enter a Personal Access Token for authentication",validate:t=>j(t)})),r}function h(e){return /^sm_pat_[a-f0-9]{16}$/.test(e?.trim()??"")}function j(e){return h(e)?!0:"Invalid Personal Access Token"}function P(){return new Command("init").option("-p, --pat <key>","Personal Access Token for authentication (BTP_PAT_TOKEN environment variable)").option("-i, --instance <url>","The url to your BTP instance, defaults to https://console.settlemint.com (BTP_INSTANCE_URL environment variable)").description("Initializes the setup of the BTP SDK").action(async({pat:e,instance:r})=>{s("Setting up the BTP SDK in your project","info");try{let t=await x(e),n=await m(r);await u({pat:t,instance:n}),s("Config file created at .btprc.json","success");}catch(t){s(t.message,"error"),console.error(t.stack),process.exit(1);}})}var T=program.description("CLI for the SettleMint Blockchain Transformation Platform SDK");T.addCommand(P());T.parse(process.argv); | ||
// package.json | ||
var package_default = { | ||
name: "@settlemint/btp-sdk-cli", | ||
version: "0.3.2", | ||
main: "./dist/index.js", | ||
module: "./dist/index.js", | ||
types: "./dist/index.d.ts", | ||
type: "module", | ||
private: false, | ||
license: "MIT", | ||
author: { | ||
name: "SettleMint", | ||
email: "support@settlemint.com", | ||
url: "https://settlemint.com" | ||
}, | ||
homepage: "https://github.com/settlemint/btp-sdk/blob/main/packages/cli/README.md", | ||
repository: { | ||
type: "git", | ||
url: "git+https://github.com/settlemint/btp-sdk.git" | ||
}, | ||
bugs: { | ||
url: "https://github.com/settlemint/btp-sdk/issues", | ||
email: "support@settlemint.com" | ||
}, | ||
files: [ | ||
"dist" | ||
], | ||
exports: { | ||
"./package.json": "./package.json", | ||
".": { | ||
types: "./dist/index.d.ts", | ||
import: "./dist/index.js" | ||
} | ||
}, | ||
bin: { | ||
"btp-sdk-cli": "dist/index.js" | ||
}, | ||
scripts: { | ||
build: "tsup src/index.ts --format esm --dts", | ||
dev: "tsup src/index.ts --format esm --dts --watch" | ||
}, | ||
devDependencies: { | ||
"@types/node": "20.14.13", | ||
tsup: "8.2.3" | ||
}, | ||
dependencies: { | ||
"@clack/prompts": "0.7.0", | ||
"@commander-js/extra-typings": "12.1.0", | ||
commander: "12.1.0", | ||
cosmiconfig: "9.0.0", | ||
dotenv: "16.4.5", | ||
"ts-deepmerge": "7.0.1", | ||
yoctocolors: "2.1.1", | ||
zod: "3.23.8" | ||
}, | ||
peerDependencies: {} | ||
}; | ||
var printAsciiArt = () => console.log( | ||
magentaBright(` | ||
_________ __ __ .__ _____ .__ __ | ||
/ _____/ _____/ |__/ |_| | ____ / \\ |__| _____/ |_ | ||
\\_____ \\_/ __ \\ __\\ __\\ | _/ __ \\ / \\ / \\| |/ \\ __\\ | ||
/ \\ ___/| | | | | |_\\ ___// Y \\ | | \\ | | ||
/_______ /\\___ >__| |__| |____/\\___ >____|__ /__|___| /__| | ||
\\/ \\/ \\/ \\/ \\/ | ||
`) | ||
); | ||
var printIntro = (msg) => intro(inverse(magentaBright(msg))); | ||
var printOutro = (msg) => outro(inverse(greenBright(msg))); | ||
var printCancel = (msg) => cancel(inverse(redBright(msg))); | ||
var promptPassword = async (options) => { | ||
const passwordResult = await password(options); | ||
if (isCancel(passwordResult)) { | ||
printCancel("Cancelled"); | ||
process.exit(0); | ||
} | ||
return passwordResult; | ||
}; | ||
var promptText = async (options) => { | ||
const textResult = await text(options); | ||
if (isCancel(textResult)) { | ||
printCancel("Cancelled"); | ||
process.exit(0); | ||
} | ||
return textResult; | ||
}; | ||
var printSpinner = async (options) => { | ||
const s = spinner(); | ||
s.start(options.startMessage); | ||
const result = await options.task(); | ||
s.stop(options.stopMessage); | ||
return result; | ||
}; | ||
function findProjectRoot(startDir) { | ||
let currentDir = startDir; | ||
while (currentDir !== path.parse(currentDir).root) { | ||
if (existsSync(path.join(currentDir, "package.json"))) { | ||
return currentDir; | ||
} | ||
currentDir = path.dirname(currentDir); | ||
} | ||
throw new Error("Unable to find project root"); | ||
} | ||
// src/lib/config.ts | ||
var ConfigSchema = z.object({ | ||
instance: z.string().default("https://console.settlemint.com") | ||
}); | ||
var EnvSchema = z.object({ | ||
BTP_PAT_TOKEN: z.string() | ||
}); | ||
ConfigSchema.extend({ | ||
pat: z.string() | ||
}); | ||
async function parseConfig() { | ||
const explorer = cosmiconfig("btp"); | ||
const result = await explorer.search(); | ||
if (result) { | ||
return ConfigSchema.parse(result.config); | ||
} | ||
return void 0; | ||
} | ||
async function createConfig(config) { | ||
const defaultConfig = {}; | ||
const preConfiguredConfig = merge(defaultConfig, config); | ||
const validatedPreConfiguredConfig = ConfigSchema.parse(preConfiguredConfig); | ||
const existingConfig = await parseConfig(); | ||
const mergedConfig = existingConfig ? merge(validatedPreConfiguredConfig, existingConfig) : preConfiguredConfig; | ||
const validatedMergedConfig = ConfigSchema.parse(mergedConfig); | ||
const projectRoot = findProjectRoot(process.cwd()); | ||
const configPath = path.join(projectRoot, ".btprc.json"); | ||
writeFileSync(configPath, JSON.stringify(validatedMergedConfig, null, 2)); | ||
} | ||
var escapeNewlines = (str) => str.replace(/\n/g, "\\n"); | ||
var format = (key, value) => `${key}=${escapeNewlines(value)}`; | ||
async function createEnv(env) { | ||
const projectRoot = findProjectRoot(process.cwd()); | ||
const envPath = path.join(projectRoot, ".env.local"); | ||
let dotEnv = {}; | ||
try { | ||
dotEnv = dotenv.parse(readFileSync(envPath, "utf-8")); | ||
} catch (e) { | ||
} | ||
const mergedEnv = merge(dotEnv, env); | ||
const validatedMergedEnv = EnvSchema.parse(mergedEnv); | ||
const contents = Object.entries(validatedMergedEnv).map(([key, value]) => format(key, value)).join("\n"); | ||
writeFileSync(envPath, contents); | ||
dotenv.config({ | ||
path: [".env.local", ".env"], | ||
override: true | ||
}); | ||
} | ||
// src/lib/instance.ts | ||
async function coerceInstanceUrl(url) { | ||
let envUrl = process.env.BTP_INSTANCE_URL || url; | ||
if (!validateInstanceUrl(envUrl)) { | ||
envUrl = await promptText({ | ||
message: "Enter the URL of your BTP instance", | ||
defaultValue: "https://console.settlemint.com", | ||
initialValue: "https://console.settlemint.com", | ||
placeholder: "https://console.settlemint.com", | ||
validate(value) { | ||
if (!validateInstanceUrl(value)) { | ||
return "Invalid BTP instance URL. Please enter a valid HTTPS URL."; | ||
} | ||
} | ||
}); | ||
} | ||
return envUrl; | ||
} | ||
function validateInstanceUrl(url) { | ||
try { | ||
const parsedUrl = new URL(url ?? ""); | ||
return parsedUrl.protocol === "https:"; | ||
} catch { | ||
return false; | ||
} | ||
} | ||
// src/lib/pat-token.ts | ||
async function coercePatToken(pat) { | ||
let envPat = pat; | ||
if (!validatePatToken(envPat)) { | ||
envPat = await promptPassword({ | ||
message: "Enter a Personal Access Token for authentication", | ||
validate(value) { | ||
if (!validatePatToken(value)) { | ||
return "Invalid Personal Access Token"; | ||
} | ||
} | ||
}); | ||
} | ||
return envPat; | ||
} | ||
function validatePatToken(pat) { | ||
return /^sm_pat_[a-f0-9]{16}$/.test(pat?.trim() ?? ""); | ||
} | ||
// src/commands/init.ts | ||
function initCommand() { | ||
return new Command("init").option("-p, --pat <key>", "Personal Access Token for authentication (BTP_PAT_TOKEN environment variable)").option( | ||
"-i, --instance <url>", | ||
"The url to your BTP instance, defaults to https://console.settlemint.com (BTP_INSTANCE_URL environment variable)" | ||
).description("Initializes the setup of the BTP SDK").action(async ({ pat, instance }) => { | ||
printAsciiArt(); | ||
printIntro("Setting up the BTP SDK in your project"); | ||
try { | ||
const personalAccessToken = await coercePatToken(pat); | ||
await printSpinner({ | ||
startMessage: "Creating or updating the .env.local file", | ||
task: async () => { | ||
await createEnv({ BTP_PAT_TOKEN: personalAccessToken }); | ||
}, | ||
stopMessage: ".env.local file created or updated" | ||
}); | ||
const instanceUrl = await coerceInstanceUrl(instance); | ||
await printSpinner({ | ||
startMessage: "Creating or updating the .btprc.json config file", | ||
task: async () => { | ||
await createConfig({ instance: instanceUrl }); | ||
}, | ||
stopMessage: ".btprc.json config file created or updated" | ||
}); | ||
printOutro("You're all set!"); | ||
} catch (error) { | ||
printCancel(`Error: ${error.message}`); | ||
console.error(error.stack); | ||
process.exit(1); | ||
} | ||
}); | ||
} | ||
// src/index.ts | ||
dotenv.config({ | ||
path: [".env.local", ".env"], | ||
override: true | ||
}); | ||
var sdkcli = new Command(); | ||
sdkcli.name("btp-sdk-cli").usage("[command]").description(`CLI for the SettleMint Blockchain Transformation Platform SDK (v${package_default.version})`).version(package_default.version, "-v, --version", "Output the current version").helpOption("-h, --help", "Display help for command").allowUnknownOption().showSuggestionAfterError(true).showHelpAfterError(); | ||
sdkcli.addCommand(initCommand()); | ||
sdkcli.parseAsync(process.argv).catch(async (reason) => { | ||
cancel("An unexpected error occurred. Please report it as a bug:"); | ||
console.error(reason); | ||
process.exit(1); | ||
}); | ||
//# sourceMappingURL=index.js.map | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@settlemint/btp-sdk-cli", | ||
"version": "0.3.4", | ||
"version": "0.3.5", | ||
"main": "./dist/index.js", | ||
@@ -42,12 +42,11 @@ "module": "./dist/index.js", | ||
"devDependencies": { | ||
"@types/node": "20.14.12", | ||
"tsup": "8.2.3", | ||
"type-fest": "4.23.0" | ||
"@types/node": "20.14.13", | ||
"tsup": "8.2.3" | ||
}, | ||
"dependencies": { | ||
"@clack/prompts": "0.7.0", | ||
"@commander-js/extra-typings": "12.1.0", | ||
"@inquirer/prompts": "5.3.2", | ||
"boxen": "8.0.0", | ||
"commander": "12.1.0", | ||
"cosmiconfig": "9.0.0", | ||
"reflect-metadata": "0.2.2", | ||
"dotenv": "16.4.5", | ||
"ts-deepmerge": "7.0.1", | ||
@@ -54,0 +53,0 @@ "yoctocolors": "2.1.1", |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
33172
53.09%2
-33.33%254
1054.55%2
-33.33%2
-33.33%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed