@contember/cli
Advanced tools
Comparing version 0.10.0-alpha.2 to 0.10.0-alpha.3
@@ -13,4 +13,4 @@ "use strict"; | ||
const workspaceDirectory = process.cwd(); | ||
const { instanceDirectory } = await instance_1.resolveInstanceEnvironmentFromInput({ input, workspaceDirectory }); | ||
await instance_1.printInstanceStatus({ instanceDirectory }); | ||
const instanceLocalEnvironment = await instance_1.resolveInstanceEnvironmentFromInput({ input, workspaceDirectory }); | ||
await instance_1.printInstanceStatus(instanceLocalEnvironment); | ||
} | ||
@@ -17,0 +17,0 @@ } |
@@ -29,4 +29,4 @@ "use strict"; | ||
const workspaceDirectory = process.cwd(); | ||
const { instanceDirectory } = await instance_1.resolveInstanceEnvironmentFromInput({ input, workspaceDirectory }); | ||
const composeConfig = await dockerCompose_1.readDefaultDockerComposeConfig(instanceDirectory); | ||
const instanceLocalEnvironment = await instance_1.resolveInstanceEnvironmentFromInput({ input, workspaceDirectory }); | ||
const composeConfig = await dockerCompose_1.readDefaultDockerComposeConfig(instanceLocalEnvironment.instanceDirectory); | ||
if (!composeConfig.services) { | ||
@@ -37,3 +37,3 @@ throw 'docker-compose is not configured'; | ||
composeConfig, | ||
instanceDirectory, | ||
instanceDirectory: instanceLocalEnvironment.instanceDirectory, | ||
host: input.getOption('host'), | ||
@@ -43,3 +43,3 @@ ports: input.getOption('ports') ? Number(input.getOption('ports')) : undefined, | ||
const withAdmin = !!composeConfig.services.admin; | ||
let dockerCompose = new dockerCompose_1.DockerCompose(instanceDirectory); | ||
let dockerCompose = new dockerCompose_1.DockerCompose(instanceLocalEnvironment.instanceDirectory); | ||
const nodeAdminRuntime = withAdmin && input.getOption('admin-runtime') === 'node'; | ||
@@ -69,3 +69,3 @@ const mainServices = ['api', ...(!withAdmin || nodeAdminRuntime ? [] : ['admin'])]; | ||
await new Promise(resolve => setTimeout(resolve, 2000)); | ||
const status = await instance_1.getInstanceStatus({ instanceDirectory }); | ||
const status = await instance_1.getInstanceStatus(instanceLocalEnvironment); | ||
const notRunning = status.filter(it => it.name !== 'admin' || !nodeAdminRuntime).filter(it => !it.running); | ||
@@ -94,3 +94,3 @@ if (notRunning.length > 0) { | ||
timeoutRef = setTimeout(async () => { | ||
await instance_1.printInstanceStatus({ instanceDirectory }); | ||
await instance_1.printInstanceStatus(instanceLocalEnvironment); | ||
printNodeAdminStatus(); | ||
@@ -116,3 +116,3 @@ }, 2000); | ||
printNodeAdminStatus(); | ||
await instance_1.printInstanceStatus({ instanceDirectory }); | ||
await instance_1.printInstanceStatus(instanceLocalEnvironment); | ||
if (input.getOption('detach')) { | ||
@@ -119,0 +119,0 @@ return; |
@@ -50,4 +50,3 @@ "use strict"; | ||
for (const instance of instances) { | ||
const instanceEnv = await instance_1.resolveInstanceEnvironment({ workspaceDirectory, instanceName: instance }); | ||
await dockerCompose_1.updateMainDockerComposeConfig(instanceEnv.instanceDirectory, (data) => { | ||
await dockerCompose_1.updateMainDockerComposeConfig(instance.instanceDirectory, (data) => { | ||
var _a; | ||
@@ -54,0 +53,0 @@ if (!((_a = data.services) === null || _a === void 0 ? void 0 : _a.api)) { |
@@ -22,11 +22,11 @@ "use strict"; | ||
exports.updateOverrideConfig = async (dir, updater) => { | ||
const path = await resolvePath(dir, OVERRIDE_CONFIGS, OVERRIDE_CONFIGS[0]); | ||
const path = process.env.COMPOSE_FILE || (await resolvePath(dir, OVERRIDE_CONFIGS, OVERRIDE_CONFIGS[0])); | ||
return yaml_1.updateYaml(path, updater, { createMissing: true }); | ||
}; | ||
exports.updateMainDockerComposeConfig = async (dir, updater) => { | ||
const path = await resolvePath(dir, MAIN_CONFIGS, MAIN_CONFIGS[0]); | ||
const path = process.env.COMPOSE_FILE || (await resolvePath(dir, MAIN_CONFIGS, MAIN_CONFIGS[0])); | ||
return yaml_1.updateYaml(path, updater, { createMissing: true }); | ||
}; | ||
exports.readDefaultDockerComposeConfig = async (dir) => { | ||
const candidates = [...MAIN_CONFIGS, ...OVERRIDE_CONFIGS]; | ||
const candidates = process.env.COMPOSE_FILE ? [process.env.COMPOSE_FILE] : [...MAIN_CONFIGS, ...OVERRIDE_CONFIGS]; | ||
return await yaml_1.readMultipleYaml(candidates.map(it => path_1.join(dir, it))); | ||
@@ -33,0 +33,0 @@ }; |
@@ -1,9 +0,9 @@ | ||
export declare const instanceDirectoryToName: (instanceDirectory: string) => string; | ||
import { InstanceLocalEnvironment } from './environment'; | ||
export declare const validateInstanceName: (name: string) => void; | ||
export declare const listInstances: (args: { | ||
export declare const listInstances: ({ workspaceDirectory, }: { | ||
workspaceDirectory: string; | ||
}) => Promise<string[]>; | ||
export declare const getDefaultInstance: ({ workspaceDirectory }: { | ||
}) => Promise<InstanceLocalEnvironment[]>; | ||
export declare const getDefaultInstance: ({ workspaceDirectory, }: { | ||
workspaceDirectory: string; | ||
}) => Promise<string>; | ||
}) => Promise<InstanceLocalEnvironment>; | ||
export declare const getInstanceDir: (args: { | ||
@@ -10,0 +10,0 @@ workspaceDirectory: string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getInstanceDir = exports.getDefaultInstance = exports.listInstances = exports.validateInstanceName = exports.instanceDirectoryToName = void 0; | ||
exports.getInstanceDir = exports.getDefaultInstance = exports.listInstances = exports.validateInstanceName = void 0; | ||
const path_1 = require("path"); | ||
const fs_1 = require("../fs"); | ||
exports.instanceDirectoryToName = (instanceDirectory) => path_1.basename(instanceDirectory) | ||
.toLocaleLowerCase() | ||
.replace(/[^-_a-z0-9]/, ''); | ||
const fs_extra_1 = require("fs-extra"); | ||
const environment_1 = require("./environment"); | ||
exports.validateInstanceName = (name) => { | ||
if (!name.match(/^[a-z][a-z0-9]*$/)) { | ||
if (!name.match(/^[a-z][-_a-z0-9]*$/)) { | ||
throw 'Invalid instance name. It can contain only alphanumeric letters and cannot start with a number'; | ||
} | ||
}; | ||
exports.listInstances = async (args) => { | ||
return (await fs_1.listDirectories(path_1.join(args.workspaceDirectory, 'instances'))).map(it => path_1.basename(it)); | ||
exports.listInstances = async ({ workspaceDirectory, }) => { | ||
const instanceDir = path_1.join(workspaceDirectory, 'instances'); | ||
if (!(await fs_extra_1.pathExists(instanceDir))) { | ||
// possibly single instance environment (todo: validate) | ||
return [ | ||
{ | ||
instanceName: path_1.basename(workspaceDirectory) | ||
.toLocaleLowerCase() | ||
.replace(/[^-_a-z0-9]/, ''), | ||
instanceDirectory: workspaceDirectory, | ||
}, | ||
]; | ||
} | ||
const instanceDirs = await fs_1.listDirectories(instanceDir); | ||
return await Promise.all(instanceDirs.map(async (it) => await environment_1.resolveInstanceEnvironment({ | ||
workspaceDirectory, | ||
instanceName: path_1.basename(it), | ||
}))); | ||
}; | ||
exports.getDefaultInstance = async ({ workspaceDirectory }) => { | ||
exports.getDefaultInstance = async ({ workspaceDirectory, }) => { | ||
const instances = await exports.listInstances({ workspaceDirectory }); | ||
if (instances.length > 1) { | ||
if (instances.length !== 1) { | ||
throw 'Please specify an instance'; | ||
@@ -21,0 +36,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import { InstanceLocalEnvironment } from './enviornment'; | ||
import { InstanceLocalEnvironment } from './environment'; | ||
export declare const createInstance: (args: { | ||
@@ -3,0 +3,0 @@ workspaceDirectory: string; |
@@ -8,3 +8,3 @@ "use strict"; | ||
const template_1 = require("../template"); | ||
const enviornment_1 = require("./enviornment"); | ||
const environment_1 = require("./environment"); | ||
const common_1 = require("./common"); | ||
@@ -30,3 +30,3 @@ const dockerCompose_1 = require("../dockerCompose"); | ||
})); | ||
return await enviornment_1.resolveInstanceEnvironment({ | ||
return await environment_1.resolveInstanceEnvironment({ | ||
workspaceDirectory: args.workspaceDirectory, | ||
@@ -33,0 +33,0 @@ instanceName: args.instanceName, |
@@ -1,2 +0,2 @@ | ||
export * from './enviornment'; | ||
export * from './environment'; | ||
export * from './configure'; | ||
@@ -3,0 +3,0 @@ export { listInstances, validateInstanceName } from './common'; |
@@ -14,3 +14,3 @@ "use strict"; | ||
exports.interactiveResolveInstanceEnvironmentFromInput = exports.validateInstanceName = exports.listInstances = void 0; | ||
__exportStar(require("./enviornment"), exports); | ||
__exportStar(require("./environment"), exports); | ||
__exportStar(require("./configure"), exports); | ||
@@ -17,0 +17,0 @@ var common_1 = require("./common"); |
@@ -1,3 +0,3 @@ | ||
import { InstanceApiEnvironment } from './enviornment'; | ||
import { InstanceApiEnvironment } from './environment'; | ||
export declare const interactiveResolveInstanceEnvironmentFromInput: (instance?: string | undefined) => Promise<InstanceApiEnvironment>; | ||
//# sourceMappingURL=interactiveUtils.d.ts.map |
@@ -9,46 +9,58 @@ "use strict"; | ||
const prompts_1 = __importDefault(require("prompts")); | ||
const enviornment_1 = require("./enviornment"); | ||
const environment_1 = require("./environment"); | ||
const createRemoteInstanceEnvironment = (instanceName) => { | ||
let baseUrl = instanceName; | ||
if (baseUrl.endsWith('/')) { | ||
baseUrl = baseUrl.substring(0, baseUrl.length - 1); | ||
} | ||
if (baseUrl.endsWith('/tenant')) { | ||
console.warn('You should pass only base URL without /tenant suffix'); | ||
baseUrl = baseUrl.substring(0, baseUrl.length - '/tenant'.length); | ||
} | ||
return { type: 'remote', baseUrl }; | ||
}; | ||
const createLocalInstanceEnvironment = async (instanceEnvironment) => { | ||
const instanceStatus = await instance_1.getInstanceStatus(instanceEnvironment); | ||
const runningApi = instanceStatus.find(it => it.name === 'api' && it.running); | ||
if (!runningApi) { | ||
throw `Instance ${instanceEnvironment.instanceName} is not running. Run instance:up first.`; | ||
} | ||
const apiServer = `http://127.0.0.1:${runningApi.ports[0].hostPort}`; | ||
return { type: 'local', ...instanceEnvironment, baseUrl: apiServer }; | ||
}; | ||
exports.interactiveResolveInstanceEnvironmentFromInput = async (instance) => { | ||
const workspaceDirectory = process.cwd(); | ||
let [instanceName] = [instance || process.env.CONTEMBER_INSTANCE]; | ||
if (!instanceName) { | ||
const instances = await instance_1.listInstances({ workspaceDirectory }); | ||
({ instanceName } = await prompts_1.default({ | ||
type: 'select', | ||
message: 'Instance', | ||
name: 'instanceName', | ||
choices: [...instances.map(it => ({ value: it, title: it })), { value: '__remote', title: 'Remote API' }], | ||
})); | ||
if (instanceName === '__remote') { | ||
; | ||
({ instanceName } = await prompts_1.default({ | ||
type: 'text', | ||
message: 'Remote API URL', | ||
name: 'instanceName', | ||
})); | ||
let instanceName = instance || process.env.CONTEMBER_INSTANCE; | ||
if (instanceName) { | ||
if (instanceName.includes('://')) { | ||
return createRemoteInstanceEnvironment(instanceName); | ||
} | ||
if (!instanceName) { | ||
throw 'Please specify an instance'; | ||
else { | ||
const instanceEnvironment = await environment_1.resolveInstanceEnvironment({ workspaceDirectory, instanceName }); | ||
return await createLocalInstanceEnvironment(instanceEnvironment); | ||
} | ||
} | ||
if (instanceName.includes('://')) { | ||
let baseUrl = instanceName; | ||
if (baseUrl.endsWith('/')) { | ||
baseUrl = baseUrl.substring(0, baseUrl.length - 1); | ||
} | ||
if (baseUrl.endsWith('/tenant')) { | ||
console.warn('You should pass only base URL without /tenant suffix'); | ||
baseUrl = baseUrl.substring(0, baseUrl.length - '/tenant'.length); | ||
} | ||
return { type: 'remote', baseUrl }; | ||
const instances = await instance_1.listInstances({ workspaceDirectory }); | ||
const { instance: selectedInstance } = await prompts_1.default({ | ||
type: 'select', | ||
message: 'Instance', | ||
name: 'instance', | ||
choices: [ | ||
...instances.map(it => ({ value: it, title: it.instanceName })), | ||
{ value: '__remote', title: 'Remote API' }, | ||
], | ||
}); | ||
if (!selectedInstance) { | ||
throw 'Please specify an instance'; | ||
} | ||
const instanceEnv = await enviornment_1.resolveInstanceEnvironment({ workspaceDirectory, instanceName }); | ||
const instanceStatus = await instance_1.getInstanceStatus(instanceEnv); | ||
const runningApi = instanceStatus.find(it => it.name === 'api' && it.running); | ||
if (!runningApi) { | ||
throw `Instance ${instanceName} is not running. Run instance:up first.`; | ||
if (selectedInstance === '__remote') { | ||
const { url } = await prompts_1.default({ | ||
type: 'text', | ||
message: 'Remote API URL', | ||
name: 'url', | ||
}); | ||
return createRemoteInstanceEnvironment(url); | ||
} | ||
const apiServer = `http://127.0.0.1:${runningApi.ports[0].hostPort}`; | ||
return { type: 'local', ...instanceEnv, baseUrl: apiServer }; | ||
return await createLocalInstanceEnvironment(selectedInstance); | ||
}; | ||
//# sourceMappingURL=interactiveUtils.js.map |
import { ContainerStatus } from '../docker'; | ||
import { InstanceLocalEnvironment } from './environment'; | ||
export declare type ServiceStatus = ContainerStatus; | ||
export declare const getInstanceStatus: ({ instanceDirectory, }: { | ||
instanceDirectory: string; | ||
}) => Promise<ServiceStatus[]>; | ||
export declare const printInstanceStatus: (args: { | ||
instanceDirectory: string; | ||
}) => Promise<void>; | ||
export declare const getInstanceStatus: ({ instanceDirectory, instanceName, }: InstanceLocalEnvironment) => Promise<ServiceStatus[]>; | ||
export declare const printInstanceStatus: (args: InstanceLocalEnvironment) => Promise<void>; | ||
//# sourceMappingURL=status.d.ts.map |
@@ -6,5 +6,4 @@ "use strict"; | ||
const dockerCompose_1 = require("../dockerCompose"); | ||
const common_1 = require("./common"); | ||
exports.getInstanceStatus = async ({ instanceDirectory, }) => { | ||
const instanceName = process.env.COMPOSE_PROJECT_NAME || common_1.instanceDirectoryToName(instanceDirectory); | ||
exports.getInstanceStatus = async ({ instanceDirectory, instanceName, }) => { | ||
instanceName = process.env.COMPOSE_PROJECT_NAME || instanceName; | ||
const runningContainers = (await dockerCompose_1.execDockerCompose(['ps', '-q'], { | ||
@@ -11,0 +10,0 @@ cwd: instanceDirectory, |
{ | ||
"name": "@contember/cli", | ||
"version": "0.10.0-alpha.2", | ||
"version": "0.10.0-alpha.3", | ||
"license": "Apache-2.0", | ||
@@ -18,9 +18,9 @@ "bin": { | ||
"dependencies": { | ||
"@contember/config-loader": "^0.10.0-alpha.2", | ||
"@contember/database-migrations": "^0.10.0-alpha.2", | ||
"@contember/dic": "^0.10.0-alpha.2", | ||
"@contember/schema": "^0.10.0-alpha.2", | ||
"@contember/schema-definition": "^0.10.0-alpha.2", | ||
"@contember/schema-migrations": "^0.10.0-alpha.2", | ||
"@contember/schema-utils": "^0.10.0-alpha.2", | ||
"@contember/config-loader": "^0.10.0-alpha.3", | ||
"@contember/database-migrations": "^0.10.0-alpha.3", | ||
"@contember/dic": "^0.10.0-alpha.3", | ||
"@contember/schema": "^0.10.0-alpha.3", | ||
"@contember/schema-definition": "^0.10.0-alpha.3", | ||
"@contember/schema-migrations": "^0.10.0-alpha.3", | ||
"@contember/schema-utils": "^0.10.0-alpha.3", | ||
"chalk": "^4.1.0", | ||
@@ -27,0 +27,0 @@ "chalk-table": "^1.0.2", |
{ | ||
"name": "@contember/template-instance", | ||
"version": "0.10.0-alpha.2", | ||
"version": "0.10.0-alpha.3", | ||
"license": "Apache-2.0", | ||
@@ -5,0 +5,0 @@ "scripts": { |
{ | ||
"name": "@contember/template-project", | ||
"version": "0.10.0-alpha.2", | ||
"version": "0.10.0-alpha.3", | ||
"license": "Apache-2.0", | ||
"devDependencies": {}, | ||
"dependencies": { | ||
"@contember/schema": "^0.10.0-alpha.2", | ||
"@contember/schema-definition": "^0.10.0-alpha.2" | ||
"@contember/schema": "^0.10.0-alpha.3", | ||
"@contember/schema-definition": "^0.10.0-alpha.3" | ||
}, | ||
@@ -10,0 +10,0 @@ "scripts": { |
{ | ||
"name": "@contember/template-workspace", | ||
"version": "0.10.0-alpha.2", | ||
"version": "0.10.0-alpha.3", | ||
"license": "Apache-2.0", | ||
@@ -15,5 +15,5 @@ "scripts": { | ||
"dependencies": { | ||
"@contember/schema": "^0.10.0-alpha.2", | ||
"@contember/schema-definition": "^0.10.0-alpha.2" | ||
"@contember/schema": "^0.10.0-alpha.3", | ||
"@contember/schema-definition": "^0.10.0-alpha.3" | ||
} | ||
} |
@@ -18,6 +18,6 @@ import { Command, CommandConfiguration, Input } from '../../cli' | ||
const workspaceDirectory = process.cwd() | ||
const { instanceDirectory } = await resolveInstanceEnvironmentFromInput({ input, workspaceDirectory }) | ||
const instanceLocalEnvironment = await resolveInstanceEnvironmentFromInput({ input, workspaceDirectory }) | ||
await printInstanceStatus({ instanceDirectory }) | ||
await printInstanceStatus(instanceLocalEnvironment) | ||
} | ||
} |
@@ -45,5 +45,5 @@ import { Command, CommandConfiguration, Input } from '../../cli' | ||
const workspaceDirectory = process.cwd() | ||
const { instanceDirectory } = await resolveInstanceEnvironmentFromInput({ input, workspaceDirectory }) | ||
const instanceLocalEnvironment = await resolveInstanceEnvironmentFromInput({ input, workspaceDirectory }) | ||
const composeConfig = await readDefaultDockerComposeConfig(instanceDirectory) | ||
const composeConfig = await readDefaultDockerComposeConfig(instanceLocalEnvironment.instanceDirectory) | ||
if (!composeConfig.services) { | ||
@@ -55,3 +55,3 @@ throw 'docker-compose is not configured' | ||
composeConfig, | ||
instanceDirectory, | ||
instanceDirectory: instanceLocalEnvironment.instanceDirectory, | ||
host: input.getOption('host'), | ||
@@ -63,3 +63,3 @@ ports: input.getOption('ports') ? Number(input.getOption('ports')) : undefined, | ||
let dockerCompose = new DockerCompose(instanceDirectory) | ||
let dockerCompose = new DockerCompose(instanceLocalEnvironment.instanceDirectory) | ||
@@ -94,3 +94,3 @@ const nodeAdminRuntime = withAdmin && input.getOption('admin-runtime') === 'node' | ||
const status = await getInstanceStatus({ instanceDirectory }) | ||
const status = await getInstanceStatus(instanceLocalEnvironment) | ||
const notRunning = status.filter(it => it.name !== 'admin' || !nodeAdminRuntime).filter(it => !it.running) | ||
@@ -120,3 +120,3 @@ if (notRunning.length > 0) { | ||
timeoutRef = setTimeout(async () => { | ||
await printInstanceStatus({ instanceDirectory }) | ||
await printInstanceStatus(instanceLocalEnvironment) | ||
printNodeAdminStatus() | ||
@@ -144,3 +144,3 @@ }, 2000) | ||
printNodeAdminStatus() | ||
await printInstanceStatus({ instanceDirectory }) | ||
await printInstanceStatus(instanceLocalEnvironment) | ||
@@ -147,0 +147,0 @@ if (input.getOption('detach')) { |
import { Command, CommandConfiguration, Input } from '../../cli' | ||
import { join } from 'path' | ||
import { createWorkspace, getWorkspaceApiVersion, updateWorkspaceApiVersion } from '../../utils/workspace' | ||
import { getWorkspaceApiVersion, updateWorkspaceApiVersion } from '../../utils/workspace' | ||
import { runCommand } from '../../utils/commands' | ||
import { listInstances, resolveInstanceEnvironment } from '../../utils/instance' | ||
import { listInstances } from '../../utils/instance' | ||
import { updateMainDockerComposeConfig } from '../../utils/dockerCompose' | ||
@@ -58,4 +58,3 @@ | ||
for (const instance of instances) { | ||
const instanceEnv = await resolveInstanceEnvironment({ workspaceDirectory, instanceName: instance }) | ||
await updateMainDockerComposeConfig(instanceEnv.instanceDirectory, (data: any) => { | ||
await updateMainDockerComposeConfig(instance.instanceDirectory, (data: any) => { | ||
if (!data.services?.api) { | ||
@@ -62,0 +61,0 @@ console.log(`docker-compose.yaml file in instance ${instance} not found, skipping`) |
@@ -6,3 +6,2 @@ import { pathExists } from 'fs-extra' | ||
import { JsonUpdateCallback, readMultipleYaml, updateYaml } from './yaml' | ||
import { dump } from 'js-yaml' | ||
import { tuple } from './tuple' | ||
@@ -24,3 +23,3 @@ | ||
export const updateOverrideConfig = async (dir: string, updater: JsonUpdateCallback): Promise<void> => { | ||
const path = await resolvePath(dir, OVERRIDE_CONFIGS, OVERRIDE_CONFIGS[0]) | ||
const path = process.env.COMPOSE_FILE || (await resolvePath(dir, OVERRIDE_CONFIGS, OVERRIDE_CONFIGS[0])) | ||
return updateYaml(path, updater, { createMissing: true }) | ||
@@ -33,3 +32,3 @@ } | ||
): Promise<void> => { | ||
const path = await resolvePath(dir, MAIN_CONFIGS, MAIN_CONFIGS[0]) | ||
const path = process.env.COMPOSE_FILE || (await resolvePath(dir, MAIN_CONFIGS, MAIN_CONFIGS[0])) | ||
return updateYaml(path, updater, { createMissing: true }) | ||
@@ -39,3 +38,3 @@ } | ||
export const readDefaultDockerComposeConfig = async (dir: string): Promise<any> => { | ||
const candidates = [...MAIN_CONFIGS, ...OVERRIDE_CONFIGS] | ||
const candidates = process.env.COMPOSE_FILE ? [process.env.COMPOSE_FILE] : [...MAIN_CONFIGS, ...OVERRIDE_CONFIGS] | ||
@@ -42,0 +41,0 @@ return await readMultipleYaml(candidates.map(it => join(dir, it))) |
import { basename, join } from 'path' | ||
import { listDirectories } from '../fs' | ||
import { pathExists } from 'fs-extra' | ||
import { InstanceLocalEnvironment, resolveInstanceEnvironment } from './environment' | ||
export const instanceDirectoryToName = (instanceDirectory: string) => | ||
basename(instanceDirectory) | ||
.toLocaleLowerCase() | ||
.replace(/[^-_a-z0-9]/, '') | ||
export const validateInstanceName = (name: string) => { | ||
if (!name.match(/^[a-z][a-z0-9]*$/)) { | ||
if (!name.match(/^[a-z][-_a-z0-9]*$/)) { | ||
throw 'Invalid instance name. It can contain only alphanumeric letters and cannot start with a number' | ||
@@ -15,9 +12,38 @@ } | ||
export const listInstances = async (args: { workspaceDirectory: string }) => { | ||
return (await listDirectories(join(args.workspaceDirectory, 'instances'))).map(it => basename(it)) | ||
export const listInstances = async ({ | ||
workspaceDirectory, | ||
}: { | ||
workspaceDirectory: string | ||
}): Promise<InstanceLocalEnvironment[]> => { | ||
const instanceDir = join(workspaceDirectory, 'instances') | ||
if (!(await pathExists(instanceDir))) { | ||
// possibly single instance environment (todo: validate) | ||
return [ | ||
{ | ||
instanceName: basename(workspaceDirectory) | ||
.toLocaleLowerCase() | ||
.replace(/[^-_a-z0-9]/, ''), | ||
instanceDirectory: workspaceDirectory, | ||
}, | ||
] | ||
} | ||
const instanceDirs = await listDirectories(instanceDir) | ||
return await Promise.all( | ||
instanceDirs.map( | ||
async it => | ||
await resolveInstanceEnvironment({ | ||
workspaceDirectory, | ||
instanceName: basename(it), | ||
}), | ||
), | ||
) | ||
} | ||
export const getDefaultInstance = async ({ workspaceDirectory }: { workspaceDirectory: string }): Promise<string> => { | ||
export const getDefaultInstance = async ({ | ||
workspaceDirectory, | ||
}: { | ||
workspaceDirectory: string | ||
}): Promise<InstanceLocalEnvironment> => { | ||
const instances = await listInstances({ workspaceDirectory }) | ||
if (instances.length > 1) { | ||
if (instances.length !== 1) { | ||
throw 'Please specify an instance' | ||
@@ -24,0 +50,0 @@ } |
@@ -5,3 +5,3 @@ import { getWorkspaceApiVersion, workspaceHasAdmin } from '../workspace' | ||
import { installTemplate } from '../template' | ||
import { InstanceLocalEnvironment, resolveInstanceEnvironment } from './enviornment' | ||
import { InstanceLocalEnvironment, resolveInstanceEnvironment } from './environment' | ||
import { getInstanceDir, validateInstanceName } from './common' | ||
@@ -8,0 +8,0 @@ import { updateMainDockerComposeConfig } from '../dockerCompose' |
@@ -1,2 +0,2 @@ | ||
export * from './enviornment' | ||
export * from './environment' | ||
export * from './configure' | ||
@@ -3,0 +3,0 @@ export { listInstances, validateInstanceName } from './common' |
@@ -1,5 +0,30 @@ | ||
import { getInstanceStatus, listInstances } from '../instance' | ||
import { getInstanceStatus, InstanceLocalApiEnvironment, InstanceLocalEnvironment, listInstances } from '../instance' | ||
import prompts from 'prompts' | ||
import { InstanceApiEnvironment, resolveInstanceEnvironment } from './enviornment' | ||
import { InstanceApiEnvironment, resolveInstanceEnvironment } from './environment' | ||
const createRemoteInstanceEnvironment = (instanceName: string): InstanceApiEnvironment => { | ||
let baseUrl = instanceName | ||
if (baseUrl.endsWith('/')) { | ||
baseUrl = baseUrl.substring(0, baseUrl.length - 1) | ||
} | ||
if (baseUrl.endsWith('/tenant')) { | ||
console.warn('You should pass only base URL without /tenant suffix') | ||
baseUrl = baseUrl.substring(0, baseUrl.length - '/tenant'.length) | ||
} | ||
return { type: 'remote', baseUrl } | ||
} | ||
const createLocalInstanceEnvironment = async ( | ||
instanceEnvironment: InstanceLocalEnvironment, | ||
): Promise<InstanceLocalApiEnvironment> => { | ||
const instanceStatus = await getInstanceStatus(instanceEnvironment) | ||
const runningApi = instanceStatus.find(it => it.name === 'api' && it.running) | ||
if (!runningApi) { | ||
throw `Instance ${instanceEnvironment.instanceName} is not running. Run instance:up first.` | ||
} | ||
const apiServer = `http://127.0.0.1:${runningApi.ports[0].hostPort}` | ||
return { type: 'local', ...instanceEnvironment, baseUrl: apiServer } | ||
} | ||
export const interactiveResolveInstanceEnvironmentFromInput = async ( | ||
@@ -9,42 +34,33 @@ instance?: string, | ||
const workspaceDirectory = process.cwd() | ||
let [instanceName] = [instance || process.env.CONTEMBER_INSTANCE] | ||
if (!instanceName) { | ||
const instances = await listInstances({ workspaceDirectory }) | ||
;({ instanceName } = await prompts({ | ||
type: 'select', | ||
message: 'Instance', | ||
name: 'instanceName', | ||
choices: [...instances.map(it => ({ value: it, title: it })), { value: '__remote', title: 'Remote API' }], | ||
})) | ||
if (instanceName === '__remote') { | ||
;({ instanceName } = await prompts({ | ||
type: 'text', | ||
message: 'Remote API URL', | ||
name: 'instanceName', | ||
})) | ||
let instanceName = instance || process.env.CONTEMBER_INSTANCE | ||
if (instanceName) { | ||
if (instanceName.includes('://')) { | ||
return createRemoteInstanceEnvironment(instanceName) | ||
} else { | ||
const instanceEnvironment = await resolveInstanceEnvironment({ workspaceDirectory, instanceName }) | ||
return await createLocalInstanceEnvironment(instanceEnvironment) | ||
} | ||
if (!instanceName) { | ||
throw 'Please specify an instance' | ||
} | ||
} | ||
if (instanceName.includes('://')) { | ||
let baseUrl = instanceName | ||
if (baseUrl.endsWith('/')) { | ||
baseUrl = baseUrl.substring(0, baseUrl.length - 1) | ||
} | ||
if (baseUrl.endsWith('/tenant')) { | ||
console.warn('You should pass only base URL without /tenant suffix') | ||
baseUrl = baseUrl.substring(0, baseUrl.length - '/tenant'.length) | ||
} | ||
return { type: 'remote', baseUrl } | ||
const instances = await listInstances({ workspaceDirectory }) | ||
const { instance: selectedInstance } = await prompts({ | ||
type: 'select', | ||
message: 'Instance', | ||
name: 'instance', | ||
choices: [ | ||
...instances.map(it => ({ value: it, title: it.instanceName })), | ||
{ value: '__remote', title: 'Remote API' }, | ||
], | ||
}) | ||
if (!selectedInstance) { | ||
throw 'Please specify an instance' | ||
} | ||
const instanceEnv = await resolveInstanceEnvironment({ workspaceDirectory, instanceName }) | ||
const instanceStatus = await getInstanceStatus(instanceEnv) | ||
const runningApi = instanceStatus.find(it => it.name === 'api' && it.running) | ||
if (!runningApi) { | ||
throw `Instance ${instanceName} is not running. Run instance:up first.` | ||
if (selectedInstance === '__remote') { | ||
const { url } = await prompts({ | ||
type: 'text', | ||
message: 'Remote API URL', | ||
name: 'url', | ||
}) | ||
return createRemoteInstanceEnvironment(url) | ||
} | ||
const apiServer = `http://127.0.0.1:${runningApi.ports[0].hostPort}` | ||
return { type: 'local', ...instanceEnv, baseUrl: apiServer } | ||
return await createLocalInstanceEnvironment(selectedInstance) | ||
} |
import { ContainerStatus, getContainersStatus } from '../docker' | ||
import { execDockerCompose } from '../dockerCompose' | ||
import { instanceDirectoryToName } from './common' | ||
import { InstanceLocalEnvironment } from './environment' | ||
@@ -9,6 +9,5 @@ export type ServiceStatus = ContainerStatus | ||
instanceDirectory, | ||
}: { | ||
instanceDirectory: string | ||
}): Promise<ServiceStatus[]> => { | ||
const instanceName = process.env.COMPOSE_PROJECT_NAME || instanceDirectoryToName(instanceDirectory) | ||
instanceName, | ||
}: InstanceLocalEnvironment): Promise<ServiceStatus[]> => { | ||
instanceName = process.env.COMPOSE_PROJECT_NAME || instanceName | ||
const runningContainers = ( | ||
@@ -32,3 +31,3 @@ await execDockerCompose(['ps', '-q'], { | ||
export const printInstanceStatus = async (args: { instanceDirectory: string }) => { | ||
export const printInstanceStatus = async (args: InstanceLocalEnvironment) => { | ||
const statusList = await getInstanceStatus(args) | ||
@@ -35,0 +34,0 @@ if (statusList.length === 0) { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
705012
8334
34
8
0