New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@settlemint/btp-sdk-cli

Package Overview
Dependencies
Maintainers
0
Versions
98
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@settlemint/btp-sdk-cli - npm Package Compare versions

Comparing version 0.3.2-main-a438d15 to 0.3.2-main1a9ceb3

903

dist/index.js
#!/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, confirm, spinner, note, isCancel, password, text, select } from '@clack/prompts';
import { Command } from '@commander-js/extra-typings';
import dotenv from 'dotenv';
import { greenBright, magentaBright, inverse, redBright } from 'yoctocolors';
import { cosmiconfig } from 'cosmiconfig';
import { writeFileSync, readFileSync, mkdirSync, existsSync } from 'node:fs';
import path, { join, parse, dirname } from 'node:path';
import { merge } from 'ts-deepmerge';
import { z } from 'zod';
import { input, password } from '@inquirer/prompts';
import { generate } from '@graphql-codegen/cli';
import { createConfig as createConfig$1 } from '@redocly/openapi-core';
import openapiTS, { astToString } from 'openapi-typescript';
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-node src/index.ts --format esm --dts",
dev: "tsup-node src/index.ts --format esm --dts --watch"
},
devDependencies: {
"@clack/prompts": "0.7.0",
"@commander-js/extra-typings": "12.1.0",
"@graphql-codegen/cli": "5.0.2",
"@tsconfig/node20": "20.1.4",
"@tsconfig/strictest": "2.0.5",
"@types/node": "20.14.13",
commander: "12.1.0",
cosmiconfig: "9.0.0",
dotenv: "16.4.5",
"openapi-typescript": "7.3.0",
"ts-deepmerge": "7.0.1",
tsup: "8.2.3",
yoctocolors: "2.1.1",
zod: "3.23.8"
},
dependencies: {
"graphql-request": "7.1.0",
"openapi-fetch": "0.10.4"
},
peerDependencies: {
graphql: "16.9.0"
}
};
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 handleCancellation = (result) => {
if (isCancel(result)) {
printCancel("Cancelled");
process.exit(0);
}
};
var promptConfirm = async (options) => {
const result = await confirm(options);
handleCancellation(result);
return result;
};
var promptPassword = async (options) => {
const result = await password(options);
handleCancellation(result);
return result;
};
var promptText = async (options) => {
const result = await text(options);
handleCancellation(result);
return result;
};
var printSpinner = async (options) => {
const s = spinner();
s.start(options.startMessage);
const result = await options.task();
s.stop(options.stopMessage);
return result;
};
var promptSelect = async (options) => {
if (options.options.length === 0) {
return void 0;
}
if (options.noneOption) {
options.options.unshift(options.noneOption);
}
const result = await select(options);
handleCancellation(result);
return result;
};
var printNote = (message, title) => note(message, title);
function findProjectRoot(startDir) {
let currentDir = startDir;
while (currentDir !== parse(currentDir).root) {
if (existsSync(join(currentDir, "package.json"))) {
return currentDir;
}
currentDir = dirname(currentDir);
}
throw new Error("Unable to find project root");
}
// src/lib/config.ts
var EnvironmentConfigSchema = z.object({
workspace: z.string(),
childWorkspace: z.string().optional(),
application: z.string(),
portal: z.string().url().optional(),
portalRest: z.string().url().optional(),
graph: z.string().url().optional(),
hasura: z.string().url().optional(),
node: z.string().url().optional()
});
var ConfigSchema = z.object({
framework: z.string(),
instance: z.string().url(),
defaultEnvironment: z.string().default("development"),
environments: z.record(z.string(), EnvironmentConfigSchema).optional()
});
var EnvSchema = z.object({
BTP_PAT_TOKEN: z.string(),
NEXT_PUBLIC_BTP_APP_URL: z.string().url().optional()
});
var ConfigEnvSchema = ConfigSchema.extend({
pat: z.string(),
appUrl: z.string().url().optional()
});
async function config() {
const config2 = await parseConfig();
if (!config2) {
return void 0;
}
return ConfigEnvSchema.parse({
...config2,
pat: process.env.BTP_PAT_TOKEN,
appUrl: process.env.NEXT_PUBLIC_BTP_APP_URL
});
}
async function parseConfig() {
const explorer = cosmiconfig("btp");
const result = await explorer.search();
if (!result) {
return void 0;
}
try {
return ConfigSchema.parse(result.config);
} catch (e) {
printCancel("Configuration file does not match the expected format. Starting fresh!");
return void 0;
}
}
async function createConfig(config2) {
const defaultConfig = {};
const preConfiguredConfig = merge(defaultConfig, config2);
const existingConfig = await parseConfig();
const mergedConfig = existingConfig ? merge(existingConfig, preConfiguredConfig) : 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).filter(([_, value]) => value !== void 0).map(([key, value]) => format(key, value)).join("\n");
writeFileSync(envPath, contents);
dotenv.config({
path: [".env.local", ".env"],
override: true
});
}
async function createGqlClient(options) {
const { framework, type, gqlUrl, personalAccessToken } = options;
const btpDir = join(findProjectRoot(process.cwd()), ".btp");
const typeDir = join(btpDir, type);
const typeGqlDir = join(typeDir, "gql");
const typeCodegenDir = join(typeGqlDir, "codegen");
const typeQueriesDir = join(findProjectRoot(process.cwd()), "graphql", type);
mkdirSync(typeCodegenDir, { recursive: true });
mkdirSync(typeQueriesDir, { recursive: true });
if (framework === "nextjs") {
writeFileSync(
`${typeGqlDir}/index.ts`,
`import { GraphQLClient } from "graphql-request";
export const ${type} = new GraphQLClient(\`\${process.env.NEXT_PUBLIC_BTP_APP_URL}/proxy/${type}\`);`
);
} else {
writeFileSync(
`${typeGqlDir}/index.ts`,
`import { GraphQLClient } from "graphql-request";
export const ${type} = new GraphQLClient('${gqlUrl}', {
headers: {
"x-auth-token": process.env.BTP_PAT_TOKEN,
},
});`
);
}
writeFileSync(
`${typeQueriesDir}/apollo.config.ts`,
`module.exports = {
client: {
includes: ["./*.graphql", "./**/*.graphql"],
service: {
name: "${type}",
url: "${gqlUrl}",
headers: {
"x-auth-token": "${personalAccessToken}",
},
},
},
};`
);
await generate(
{
errorsOnly: true,
silent: true,
ignoreNoDocuments: true,
generates: {
[`${typeCodegenDir}/`]: {
preset: "client",
schema: [
{
[gqlUrl]: {
headers: {
"x-auth-token": personalAccessToken
}
}
}
],
documents: [`./${typeQueriesDir}/*.graphql`, `./${typeQueriesDir}/**/*.graphql`],
presetConfig: {
useTypeImports: true,
nonOptionalTypename: true,
dedupeFragments: true,
avoidOptionals: true,
fragmentMasking: false
},
config: {
scalars: {
BigInt: "string",
BigDecimal: "string",
date: "Date | string",
Bytes: "string",
Int8: "number",
Upload: "Blob",
Timestamp: "number"
},
strictScalars: false
}
}
}
},
true
);
}
async function createRestClient(options) {
const { framework, restURL, personalAccessToken } = options;
if (restURL) {
const redocly = await createConfig$1(
{
rules: {
"operation-operationId-unique": { severity: "error" }
},
resolve: {
http: {
headers: [
{
matches: `${new URL(restURL).protocol}://${new URL(restURL).host}/**`,
name: "x-auth-token",
value: personalAccessToken
}
]
}
}
},
{ extends: ["recommended"] }
);
const ast = await openapiTS(new URL(`${personalAccessToken}/docs/json`, restURL), {
redocly
});
const contents = astToString(ast);
const btpDir = join(findProjectRoot(process.cwd()), ".btp");
const portalDir = join(btpDir, "portal");
const restDir = join(portalDir, "rest");
const restCodegenDir = join(restDir, "codegen");
mkdirSync(restCodegenDir, { recursive: true });
const portalRestTypesPath = join(restCodegenDir, "portal-schema.d.ts");
writeFileSync(portalRestTypesPath, contents);
const portalRestClientPath = join(restDir, "index.ts");
if (framework === "nextjs") {
writeFileSync(
portalRestClientPath,
`
import createClient from "openapi-fetch";
import type { paths } from "./codegen/portal-schema";
export const portal = createClient<paths>({ baseUrl: \`\${process.env.NEXT_PUBLIC_BTP_APP_URL}/proxy/portal/rest\` });
`
);
} else {
writeFileSync(
portalRestClientPath,
`
import createClient from "openapi-fetch";
import type { paths } from "./codegen/portal-schema";
if(!process.env.BTP_PAT_TOKEN){
throw new Error("BTP_PAT_TOKEN environment variable is required");
}
export const portal = createClient<paths>({ baseUrl: '${restURL}', headers: { "x-auth-token": process.env.BTP_PAT_TOKEN } });
`
);
}
}
}
// src/commands/codegen.ts
function codegenCommand() {
return new Command("codegen").description("Generates the code for using the BTP services").option("-e, --environment <id>", "The name of the environment to use (BTP_ENVIRONMENT environment variable)").action(async ({ environment }) => {
printAsciiArt();
printIntro("Code generating");
try {
const cfg = await config();
if (!cfg) {
printCancel("No configuration found");
process.exit(0);
}
const { pat, defaultEnvironment, environments } = cfg;
if (!environments) {
printCancel("No environments found in configuration");
process.exit(0);
}
const environmentConfig = environments[process.env.BTP_ENVIRONMENT ?? environment ?? defaultEnvironment];
if (!environmentConfig) {
printCancel("No environment found");
process.exit(0);
}
const { portalRest, portal } = environmentConfig;
let usageMessage = "";
if (portalRest) {
await printSpinner({
startMessage: "Generating the Portal REST client",
task: async () => {
await createRestClient({ framework: cfg.framework, restURL: portalRest, personalAccessToken: pat });
},
stopMessage: "Portal REST client generated"
});
usageMessage += `
To use the Portal REST client:
${greenBright("import { portal } from './.btp/portal/rest'")}
${greenBright("// leverage typescript autocomplete for other methods and params")}
${greenBright("const pendingTransactions = await portal.get('/transactions/pending')")}
`;
}
if (portal) {
await printSpinner({
startMessage: "Generating the Portal GQL client",
task: async () => {
await createGqlClient({
framework: cfg.framework,
type: "portal",
gqlUrl: portal,
personalAccessToken: pat
});
},
stopMessage: "Portal GQL client generated"
});
usageMessage += `
To use the Portal GQL client:
${greenBright("import { portal } from './.btp/portal/gql/portal'")}
${greenBright("// leverage typescript autocomplete for other methods and params")}
${greenBright("const pendingTransactions = await portal.get('/transactions/pending')")}
`;
}
printNote(usageMessage, "Usage hints");
printOutro("Code generation complete");
process.exit(0);
} catch (error) {
printCancel(`Error: ${error.message}`);
console.error(error.stack);
process.exit(1);
}
});
}
// src/lib/cluster-manager.ts
async function getServices({ instance, pat }) {
const result = await fetch(`${instance}/cm/sdk/services`, {
headers: {
"Content-Type": "application/json",
"x-auth-token": pat
}
});
if (!result.ok) {
console.warn(`Failed to fetch services. Status: ${result.status}`);
return [];
}
const services = await result.json();
return services;
}
// src/lib/coerce.ts
async function coerceText(options) {
const {
configValue,
defaultValue,
invalidMessage,
existingMessage,
type,
promptMessage,
envValue,
cliParamValue,
validate
} = options;
let value = envValue || cliParamValue || configValue || defaultValue;
try {
if (validate(value)) {
const change = await promptConfirm({
message: type === "password" ? existingMessage : `${existingMessage} (${value})`,
initialValue: false
});
if (!change) {
return value;
}
}
} catch {
}
if (type === "password") {
value = await promptPassword({
message: promptMessage,
validate(value2) {
try {
if (!validate(value2)) {
return invalidMessage;
}
return;
} catch {
return invalidMessage;
}
}
});
} else {
value = await promptText({
message: promptMessage,
defaultValue,
initialValue: value ?? defaultValue,
placeholder: value ?? defaultValue,
validate(value2) {
try {
if (!validate(value2)) {
return invalidMessage;
}
return;
} catch {
return invalidMessage;
}
}
});
}
return value;
}
async function coerceSelect(params) {
const {
skipCoerce,
configValue,
options,
noneOption,
existingMessage,
promptMessage,
envValue,
cliParamValue,
validate
} = params;
let value = envValue || cliParamValue || configValue;
if (!skipCoerce) {
try {
if (validate(value)) {
const change = await promptConfirm({
message: `${existingMessage} (${// biome-ignore lint/suspicious/noExplicitAny: <explanation>
typeof value === "string" ? value : value ? value.name : ""})`,
initialValue: false
});
if (!change) {
return value;
}
}
} catch {
}
}
value = await promptSelect({
options,
message: promptMessage,
noneOption
});
if (noneOption && value === noneOption.value) {
return void 0;
}
return value;
}
// 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)"
).option(
"-au, --appUrl <url>",
"The development url to your application, defaults to http://localhost:3000 (NEXT_PUBLIC_BTP_APP_URL environment variable)"
).option("-w, --workspace <id>", "The id of the workspace to use (BTP_WORKSPACE environment variable)").option(
"-cw, --childWorkspace <id>",
"The id of the child workspace to use (BTP_CHILD_WORKSPACE environment variable)"
).option("-e, --environment <id>", "The name of the environment to use (BTP_ENVIRONMENT environment variable)").option("-a, --application <id>", "The id of the application to use (BTP_APPLICATION environment variable)").option("-pr, --portalRest <url>", "The url to the portal rest api (BTP_PORTAL_REST_URL environment variable)").option("-pg, --portalGql <url>", "The url to the portal gql api (BTP_PORTAL_GQL_URL environment variable)").option("-tg, --theGrapqh <url>", "The url to the graph gql api (BTP_THE_GRAPH_GQL_URL environment variable)").option("-h, --hasura <url>", "The url to the hasura gql api (BTP_HASURA_GQL_URL environment variable)").option("-n, --node <url>", "The url to the node rpc api (BTP_NODE_URL environment variable)").option("-f, --framework <framework>", "The framework to use (BTP_FRAMEWORK environment variable)").option("-c, --create", "Create a new environment if it does not exist (BTP_CREATE environment variable)").description("Initializes the setup of the BTP SDK").action(
async ({
pat,
instance,
appUrl,
portalRest,
portalGql,
theGrapqh,
hasura,
node,
workspace,
application,
childWorkspace,
framework,
environment,
create
}) => {
printAsciiArt();
printIntro("Setting up the BTP SDK in your project");
try {
let cfg;
try {
cfg = await config();
} catch {
}
const frameworks = [
{ value: "nodejs", label: "NodeJS" },
{ value: "nextjs", label: "Next.js" }
];
const selectedFramework = await coerceSelect({
options: frameworks,
envValue: process.env.BTP_FRAMEWORK,
cliParamValue: framework,
configValue: cfg?.framework,
validate: (value) => frameworks.map((fr) => fr.value).includes(value ?? ""),
promptMessage: "Which framework do you want to use?",
existingMessage: "A valid framework is already provided. Do you want to change it?"
});
if (!selectedFramework) {
printCancel("No framework selected");
process.exit(0);
}
const personalAccessToken = await coerceText({
type: "password",
envValue: process.env.BTP_PAT_TOKEN,
cliParamValue: pat,
configValue: cfg?.pat,
validate: (value) => /^sm_pat_[a-f0-9]{16}$/.test(value?.trim() ?? ""),
promptMessage: "Enter a Personal Access Token for authentication",
existingMessage: "A valid Personal Access Token is already provided. Do you want to change it?",
invalidMessage: "Invalid Personal Access Token"
});
const instanceUrl = await coerceText({
type: "text",
envValue: process.env.BTP_INSTANCE_URL,
cliParamValue: instance,
defaultValue: "https://console.settlemint.com",
configValue: cfg?.instance,
validate: (value) => new URL(value ?? "").protocol === "https:",
promptMessage: "Enter the URL of your BTP instance",
existingMessage: "A valid BTP instance URL is already provided. Do you want to change it?",
invalidMessage: "Invalid BTP instance URL. Please enter a valid HTTPS URL."
});
const possibleEnvironments = Object.keys(cfg?.environments ?? {});
if (possibleEnvironments.length === 0) {
possibleEnvironments.push("development");
}
let createEnvironment = !!process.env.BTP_CREATE || !!create;
if (!createEnvironment) {
createEnvironment = await promptConfirm({
message: `Do you want to create a new environment? (${possibleEnvironments.join(", ")})`,
initialValue: false
});
}
let currentEnvironment;
if (!createEnvironment) {
currentEnvironment = await coerceSelect({
options: possibleEnvironments.map((penv) => ({
value: penv,
label: penv
})),
envValue: process.env.BTP_ENVIRONMENT,
cliParamValue: environment,
configValue: cfg?.defaultEnvironment,
validate: (value) => !!value?.trim(),
promptMessage: "Select an environment to configure",
existingMessage: "A valid default environment is already provided. Do you want to add one?",
skipCoerce: true
});
} else {
currentEnvironment = await coerceText({
type: "text",
envValue: process.env.BTP_ENVIRONMENT,
cliParamValue: void 0,
configValue: void 0,
validate: (value) => !!value?.trim() && !possibleEnvironments.includes(value),
promptMessage: "Enter a new environment name",
existingMessage: "A valid environment name is already provided. Do you want to change it?",
invalidMessage: "Invalid environment name or it already exists. Please enter a valid name."
});
possibleEnvironments.push(currentEnvironment);
}
if (!currentEnvironment) {
printCancel("No environment selected");
process.exit(0);
}
let selectedAppUrl;
if (selectedFramework === "nextjs") {
selectedAppUrl = await coerceText({
type: "text",
envValue: process.env.NEXT_PUBLIC_BTP_APP_URL,
cliParamValue: appUrl,
configValue: cfg?.appUrl,
validate: (value) => !!new URL(value ?? "").toString(),
promptMessage: "Enter the development URL of your application instance",
existingMessage: "A valid application URL is already provided. Do you want to change it?",
invalidMessage: "Invalid application instance URL. Please enter a valid URL."
});
}
const services = await printSpinner({
startMessage: "Fetching services",
task: async () => {
return getServices({ instance: instanceUrl, pat: personalAccessToken });
},
stopMessage: "Services fetched"
});
if (services.length === 0) {
printCancel("No workspaces found using the provided personal access token");
process.exit(0);
}
const selectedWorkspace = await coerceSelect({
options: services.map((service) => ({
value: service,
label: service.name
})),
envValue: services.find((svc) => svc.id === process.env.BTP_WORKSPACE),
cliParamValue: services.find((svc) => svc.id === workspace),
configValue: services.find((svc) => svc.id === cfg?.environments?.[currentEnvironment]?.workspace),
validate: (value) => !!value?.id,
promptMessage: "Select a top level workspace",
existingMessage: "A valid top level workspace is already provided. Do you want to change it?"
});
if (!selectedWorkspace) {
printCancel("No workspace selected");
process.exit(0);
}
let lowestWorkspace = selectedWorkspace;
let selectedChildWorkspace;
if (selectedWorkspace.childWorkspaces.length > 0) {
const list = [
{ ...selectedWorkspace, name: `Top level: ${selectedWorkspace.name}` },
...selectedWorkspace.childWorkspaces
];
const options = list.map((childWorkspace2) => ({
value: childWorkspace2,
label: childWorkspace2.name
}));
selectedChildWorkspace = await coerceSelect({
options,
envValue: list.find((svc) => svc.id === process.env.BTP_CHILD_WORKSPACE),
cliParamValue: list.find((svc) => svc.id === childWorkspace),
configValue: list.find((svc) => svc.id === cfg?.environments?.[currentEnvironment]?.childWorkspace),
validate: (value) => !!value?.id,
promptMessage: "Select a child workspace",
existingMessage: "A valid child workspace is already provided. Do you want to change it?"
});
if (!selectedChildWorkspace) {
printCancel("No sub-workspace selected");
process.exit(0);
}
lowestWorkspace = selectedChildWorkspace;
}
if (lowestWorkspace.applications.length === 0) {
printCancel("No applications found using the provided personal access token and workspace");
process.exit(0);
}
const selectedApplication = await coerceSelect({
options: lowestWorkspace.applications.map((app) => ({ value: app, label: app.name })),
envValue: lowestWorkspace.applications.find((svc) => svc.id === process.env.BTP_APPLICATION),
cliParamValue: lowestWorkspace.applications.find((svc) => svc.id === application),
configValue: lowestWorkspace.applications.find(
(svc) => svc.id === cfg?.environments?.[currentEnvironment]?.application
),
validate: (value) => !!value?.id,
promptMessage: "Select an application",
existingMessage: "A valid application is already provided. Do you want to change it?"
});
if (!selectedApplication) {
printCancel("No application selected");
process.exit(0);
}
const portalRestUrl = await coerceSelect({
options: selectedApplication.portals.map((portal) => ({
value: portal.restUrl,
label: `${portal.name} (${portal.uniqueName})`
})),
noneOption: { value: void 0, label: "None" },
envValue: process.env.BTP_PORTAL_REST_URL,
cliParamValue: portalRest,
configValue: cfg?.environments?.[currentEnvironment]?.portalRest,
validate: (value) => !!new URL(value ?? "").toString(),
promptMessage: "Select your Smart Contract Set Portal instance (REST API)",
existingMessage: "A valid Smart Contract Set Portal instance URL for REST is already provided. Do you want to change it?"
});
const portalGqlUrl = await coerceSelect({
options: selectedApplication.portals.map((portal) => ({
value: portal.gqlUrl,
label: `${portal.name} (${portal.uniqueName})`
})),
noneOption: { value: void 0, label: "None" },
envValue: process.env.BTP_PORTAL_GQL_URL,
cliParamValue: portalGql,
configValue: cfg?.environments?.[currentEnvironment]?.portal,
validate: (value) => !!new URL(value ?? "").toString(),
promptMessage: "Select your Smart Contract Set Portal instance (GraphQL API)",
existingMessage: "A valid Smart Contract Set Portal instance URL for GraphQL is already provided. Do you want to change it?"
});
const thegraphGqlUrl = await coerceSelect({
options: selectedApplication.graphs.map((graph) => ({
value: graph.gqlUrl,
label: `${graph.name} (${graph.uniqueName})`
})),
noneOption: { value: void 0, label: "None" },
envValue: process.env.BTP_THE_GRAPH_GQL_URL,
cliParamValue: theGrapqh,
configValue: cfg?.environments?.[currentEnvironment]?.graph,
validate: (value) => !!new URL(value ?? "").toString(),
promptMessage: "Select your The Graph instance",
existingMessage: "A valid The Graph URL is already provided. Do you want to change it?"
});
const hasuraUrl = await coerceSelect({
options: selectedApplication.hasuras.map((hasura2) => ({
value: hasura2.gqlUrl,
label: `${hasura2.name} (${hasura2.uniqueName})`
})),
noneOption: { value: void 0, label: "None" },
envValue: process.env.BTP_HASURA_GQL_URL,
cliParamValue: hasura,
configValue: cfg?.environments?.[currentEnvironment]?.hasura,
validate: (value) => !!new URL(value ?? "").toString(),
promptMessage: "Select your Hasura instance",
existingMessage: "A valid Hasura URL is already provided. Do you want to change it?"
});
const nodeUrl = await coerceSelect({
options: selectedApplication.nodes.map((node2) => ({
value: node2.rpcUrl,
label: `${node2.name} (${node2.uniqueName})`
})),
noneOption: { value: void 0, label: "None" },
envValue: process.env.BTP_NODE_URL,
cliParamValue: node,
configValue: cfg?.environments?.[currentEnvironment]?.node,
validate: (value) => !!new URL(value ?? "").toString(),
promptMessage: "Select a blockchain node or loadbalancer",
existingMessage: "A valid blockchain node URL is already provided. Do you want to change it?"
});
await printSpinner({
startMessage: "Creating or updating the .env.local file",
task: async () => {
await createEnv({ BTP_PAT_TOKEN: personalAccessToken, NEXT_PUBLIC_BTP_APP_URL: selectedAppUrl });
},
stopMessage: ".env.local file created or updated"
});
const defaultEnvironment = await coerceSelect({
options: possibleEnvironments.map((penv) => ({
value: penv,
label: penv
})),
configValue: cfg?.defaultEnvironment,
validate: (value) => !!value?.trim(),
promptMessage: "Select a default environment (used when no environment is specified)",
existingMessage: "A valid default environment is already provided. Do you want to select a different one?"
});
if (!defaultEnvironment) {
printCancel("No default environment selected");
process.exit(0);
}
await printSpinner({
startMessage: "Creating or updating the .btprc.json config file",
task: async () => {
await createConfig({
defaultEnvironment,
framework: selectedFramework,
instance: instanceUrl,
environments: {
[currentEnvironment]: {
workspace: selectedWorkspace.id,
childWorkspace: selectedChildWorkspace?.id,
application: selectedApplication.id,
portal: portalGqlUrl,
portalRest: portalRestUrl,
graph: thegraphGqlUrl,
hasura: hasuraUrl,
node: nodeUrl
}
}
});
},
stopMessage: ".btprc.json config file created or updated"
});
printNote(
`To generate the code for using the BTP services, run the following command:
${greenBright("btp-sdk-cli codegen")}
or for another environment:
${greenBright(`btp-sdk-cli codegen -e <${possibleEnvironments.join(" | ")}>`)}`,
"Next steps"
);
printOutro("You're all set!");
process.exit(0);
} 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.addCommand(codegenCommand());
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

31

package.json
{
"name": "@settlemint/btp-sdk-cli",
"version": "0.3.2-main-a438d15",
"version": "0.3.2-main1a9ceb3",
"main": "./dist/index.js",

@@ -38,21 +38,28 @@ "module": "./dist/index.js",

"scripts": {
"build": "tsup src/index.ts --format esm --dts",
"dev": "tsup src/index.ts --format esm --dts --watch"
"build": "tsup-node src/index.ts --format esm --dts",
"dev": "tsup-node src/index.ts --format esm --dts --watch"
},
"devDependencies": {
"@types/node": "20.14.12",
"tsup": "8.2.3",
"type-fest": "4.23.0"
},
"dependencies": {
"@clack/prompts": "0.7.0",
"@commander-js/extra-typings": "12.1.0",
"@inquirer/prompts": "5.3.2",
"boxen": "8.0.0",
"@graphql-codegen/cli": "5.0.2",
"@tsconfig/node20": "20.1.4",
"@tsconfig/strictest": "2.0.5",
"@types/node": "20.14.13",
"commander": "12.1.0",
"cosmiconfig": "9.0.0",
"reflect-metadata": "0.2.2",
"dotenv": "16.4.5",
"openapi-typescript": "7.3.0",
"ts-deepmerge": "7.0.1",
"tsup": "8.2.3",
"yoctocolors": "2.1.1",
"zod": "3.23.8"
},
"peerDependencies": {}
"dependencies": {
"graphql-request": "7.1.0",
"openapi-fetch": "0.10.4"
},
"peerDependencies": {
"graphql": "16.9.0"
}
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc