@tokens-studio/sdk
Version:
The official SDK for Tokens Studio
179 lines • 6.11 kB
JavaScript
/* eslint-disable no-console */
import path from 'node:path';
import fs from 'node:fs/promises';
import { tasks } from '@tokens-studio/cli-kit';
import chalk from 'chalk';
import { prompt } from '../utils/prompt.js';
import { error, info } from '../utils/messages.js';
import { createClient } from '../utils/client.js';
import { configFileName } from '../utils/constants.js';
import { getOrgs, getProjects } from '../utils/queries.js';
import { getVersion } from '../utils/get-version.js';
import { fetchPaginatedData } from '../utils/fetch-paginated-data.js';
async function createConfigFile(project, configPath, host) {
const { org, id, branch } = project;
const filepath = path.resolve(configPath ?? '', configFileName);
let shouldWrite = true;
let fileExists = true;
try {
await fs.lstat(filepath);
}
catch {
fileExists = false;
}
if (fileExists) {
const { overwriteFile } = await prompt([
{
name: 'overwriteFile',
type: 'confirm',
label: '',
message: `File ${chalk.cyanBright(filepath)} already exists, do you want to overwrite it?`,
initial: true,
},
], {}, { name: 'overwriteFile', value: true });
shouldWrite = !!overwriteFile;
}
if (!shouldWrite)
return;
const dirPath = path.dirname(filepath);
let directoryExists = false;
try {
const stat = await fs.lstat(dirPath);
if (stat.isDirectory()) {
directoryExists = true;
}
}
catch {
await fs.mkdir(dirPath, { recursive: true });
directoryExists = true;
}
if (directoryExists) {
const configData = {
version: getVersion().split('.')[0],
org,
project: id,
output: 'studio-export',
};
// Only include host in config if it was explicitly provided
if (host) {
configData.host = host;
}
// Only include branch in config if it's different from main
if (branch && branch !== 'main') {
configData.branch = branch;
}
await fs.writeFile(filepath, JSON.stringify(configData, null, 2));
console.log(`\n ${chalk.bold('Successfully wrote your settings to')} ${chalk.cyanBright(filepath)}`);
}
else {
throw new Error(`File already exists at config folder path ${dirPath}, which means we cannot create the ${configFileName} file.`);
}
}
async function selectProject(client) {
let orgs = [];
let projects = [];
console.log('\r');
await tasks({
start: 'Fetching data',
end: 'Done!',
}, [
{
pending: 'orgs',
start: `Getting organizations`,
end: `Fetched organizations`,
while: async () => {
orgs = await fetchPaginatedData(client, getOrgs);
},
onError(e) {
error(e);
},
},
{
pending: 'projects',
start: `Getting projects & branches`,
end: `Fetched projects`,
while: async () => {
const projectsData = await Promise.all(orgs.map(({ id }) => fetchPaginatedData(client, getProjects, { org: id })));
projects = projectsData.flatMap((projs) => {
return projs.map((proj) => {
const { id, name, organizationId: org, branches } = proj;
// TODO: use different branch than default if specified in config
const branch = (branches.data.find((b) => b.isDefault) ??
branches.data[0] ?? { name: 'main' }).name;
return { id, name, org, branch };
});
});
},
onError(e) {
error(e);
throw e;
},
},
]);
if (projects.length === 0) {
error(`Your API key does not have access to any existing Studio App projects.`);
return;
}
else if (projects.length === 1) {
info(`Only 1 project available, so we will preselect ${projects[0].name} for you`);
return projects[0];
}
let org;
if (orgs.length === 1) {
info(`Only 1 organization available, so we will preselect ${orgs[0].name} for you`);
org = orgs[0].id;
}
else {
const answer = await prompt([
{
name: 'org',
type: 'select',
label: '',
message: 'Select your organization',
choices: orgs.map((org) => ({
value: org.id,
label: org.name,
})),
initial: orgs[0]?.id,
},
], {}, { name: 'org', value: orgs[0].id });
org = answer.org;
}
if (!org) {
return;
}
const orgProjects = projects.filter((proj) => proj.org === org);
let proj;
if (orgProjects.length === 0) {
error('No projects available for this organization.');
}
else if (orgProjects.length === 1) {
info(`Only 1 project available, so we will preselect ${orgProjects[0].name} for you`);
proj = orgProjects[0];
}
else {
const answer = await prompt([
{
name: 'proj',
type: 'select',
label: '',
message: 'Select your project',
choices: orgProjects.map((proj) => ({
value: proj,
label: proj.name,
})),
initial: orgProjects[0],
},
], {}, { name: 'proj', value: orgProjects[0] });
proj = answer.proj;
}
return proj;
}
export async function setup(args) {
const client = createClient(args);
const project = await selectProject(client);
if (project) {
await createConfigFile(project, args['--config'], args['--host']);
}
}
//# sourceMappingURL=setup.js.map