@govuk-pay/cli 0.0.31 → 0.0.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,18 +3,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.loadClusterConfig = exports.PayLocalCluster = void 0;
6
+ exports.loadServicesConfig = exports.loadClusterConfig = exports.PayLocalCluster = exports.CLUSTERS = void 0;
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const yaml_1 = __importDefault(require("yaml"));
10
10
  const md5_js_1 = require("../../../util/md5.js");
11
+ exports.CLUSTERS = ['all', 'admin', 'card', 'paymentlinks', 'webhooks', 'endtoend', 'java', 'toolbox'];
11
12
  // This is the complete cluster configuration that will be used as the context for template rendering
12
13
  class PayLocalCluster {
13
14
  name;
14
15
  payServices;
15
16
  dbServices;
16
17
  reverseProxyServices;
17
- egressProxy;
18
18
  javaApps;
19
19
  nodeApps;
20
20
  localJavaApps;
@@ -29,6 +29,7 @@ class PayLocalCluster {
29
29
  requiresEgressProxy;
30
30
  serviceURLEnvVars;
31
31
  mountLocalNodeApps;
32
+ mountPayJSCommons;
32
33
  noProxyEnvVar;
33
34
  defaultServiceConfigsPath;
34
35
  environmentOverridesPath;
@@ -38,7 +39,6 @@ class PayLocalCluster {
38
39
  this.payServices = clusterConfig.payServices;
39
40
  this.dbServices = clusterConfig.dbServices;
40
41
  this.reverseProxyServices = clusterConfig.reverseProxyServices;
41
- this.egressProxy = clusterConfig.egressProxy;
42
42
  this.javaApps = this.payServices.filter((service) => service.serviceType === PayServiceType.Java);
43
43
  this.nodeApps = this.payServices.filter((service) => service.serviceType === PayServiceType.Node);
44
44
  this.remoteJavaApps = this.javaApps.filter((service) => service.localBuild);
@@ -49,8 +49,9 @@ class PayLocalCluster {
49
49
  this.anyNodeApps = this.nodeApps.length >= 0;
50
50
  this.requiresLocalStack = this.payServices.some((service) => service.requiresLocalStack);
51
51
  this.requiresRedis = this.payServices.some((service) => service.usesRedis);
52
- this.requiresEgressProxy = this.egressProxy !== undefined;
52
+ this.requiresEgressProxy = clusterConfig.egressProxy;
53
53
  this.mountLocalNodeApps = clusterConfig.mountLocalNodeApps;
54
+ this.mountPayJSCommons = clusterConfig.mountPayJSCommons;
54
55
  this.serviceURLEnvVars = [
55
56
  this.javaApps.map((javaService) => envVarForJavaService(javaService)),
56
57
  this.nodeApps.map((nodeService) => envVarForNodeService(nodeService))
@@ -64,7 +65,7 @@ class PayLocalCluster {
64
65
  this.payServices.map((service) => service.name),
65
66
  this.dbServices.map((service) => service.name),
66
67
  this.reverseProxyServices.map((service) => service.name),
67
- this.egressProxy === undefined ? [] : this.egressProxy.name
68
+ this.requiresEgressProxy ? [] : ['egress']
68
69
  ].flat().join(',');
69
70
  this.environmentOverridesPath = clusterConfig.environmentOverridesPath;
70
71
  this.defaultServiceConfigsPath = clusterConfig.defaultServiceConfigsPath;
@@ -89,9 +90,7 @@ var PayServiceType;
89
90
  PayServiceType["Node"] = "node";
90
91
  })(PayServiceType || (PayServiceType = {}));
91
92
  function loadClusterConfig(options, workspace, defaultServiceConfigsPath, environmentOverridesPath) {
92
- const servicesConfigPath = node_path_1.default.join(__dirname, '..', '..', '..', '..', 'resources', 'pay-local', 'config', 'service_config.yaml');
93
- const serviceConfigFileContents = node_fs_1.default.readFileSync(servicesConfigPath, 'utf8');
94
- const servicesConfig = yaml_1.default.parse(serviceConfigFileContents);
93
+ const servicesConfig = loadServicesConfig();
95
94
  const payServices = [];
96
95
  for (const [, serviceConfig] of Object.entries(servicesConfig)) {
97
96
  if (includeAppInCluster(options.cluster, options, serviceConfig)) {
@@ -116,15 +115,23 @@ function loadClusterConfig(options, workspace, defaultServiceConfigsPath, enviro
116
115
  name: options.cluster,
117
116
  payServices,
118
117
  dbServices,
118
+ egressProxy: options.withEgressProxy,
119
119
  reverseProxyServices,
120
120
  workspace,
121
- mountLocalNodeApps: options.mount_local_node_apps,
121
+ mountLocalNodeApps: options.mountLocalNodeApps,
122
+ mountPayJSCommons: options.mountPayJSCommons,
122
123
  defaultServiceConfigsPath,
123
124
  environmentOverridesPath
124
125
  };
125
126
  return new PayLocalCluster(clusterConfig);
126
127
  }
127
128
  exports.loadClusterConfig = loadClusterConfig;
129
+ function loadServicesConfig() {
130
+ const servicesConfigPath = node_path_1.default.join(__dirname, '..', '..', '..', '..', 'resources', 'pay-local', 'config', 'service_config.yaml');
131
+ const serviceConfigFileContents = node_fs_1.default.readFileSync(servicesConfigPath, 'utf8');
132
+ return yaml_1.default.parse(serviceConfigFileContents);
133
+ }
134
+ exports.loadServicesConfig = loadServicesConfig;
128
135
  function includeAppInCluster(cluster, options, serviceConfig) {
129
136
  if (cluster === 'all' || cluster === 'nuke' || serviceConfig.clusters.includes(cluster)) {
130
137
  if (options.apps.length === 0 || options.apps.includes(serviceConfig.name)) {
@@ -166,7 +173,7 @@ function payServiceFromPayServiceConfig(config, upOptions, environmentOverridesP
166
173
  hasSNSTopics: snsTopics.length > 0,
167
174
  hasProxy: config.proxy === undefined ? false : config.proxy,
168
175
  hasDB: config.db,
169
- useEgressProxy: config.can_use_egress_proxy === undefined ? false : config.can_use_egress_proxy && upOptions.with_egress_proxy,
176
+ useEgressProxy: config.can_use_egress_proxy === undefined ? false : config.can_use_egress_proxy && upOptions.withEgressProxy,
170
177
  dependsOn: config.db ? [`${config.name}_db`] : [],
171
178
  expose: [],
172
179
  payServiceConfig: config,
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handler = exports.builder = exports.desc = exports.command = void 0;
7
+ const app_client_js_1 = __importDefault(require("../app_client/app_client.js"));
8
+ const standardContent_1 = require("../../../core/standardContent");
9
+ exports.command = 'account';
10
+ exports.desc = 'Create a local gateway account';
11
+ const builder = (yargs) => {
12
+ return yargs.usage(`$0 local account [--service-id <SERVICE_ID>]\n\n${exports.desc}`)
13
+ .option('service-id', {
14
+ type: 'string',
15
+ description: 'ID of an existing service'
16
+ });
17
+ };
18
+ exports.builder = builder;
19
+ exports.handler = accountHandler;
20
+ async function accountHandler(argv) {
21
+ await (0, standardContent_1.showHeader)();
22
+ const serviceId = argv.serviceId;
23
+ if (await app_client_js_1.default.isUnhealthy('adminusers')) {
24
+ console.error('The adminusers service is unhealthy, so an account cannot be created');
25
+ return;
26
+ }
27
+ if (await app_client_js_1.default.isUnhealthy('connector')) {
28
+ console.error('The connector service is unhealthy, so an account cannot be created');
29
+ return;
30
+ }
31
+ let serviceExternalId;
32
+ if (serviceId === undefined) {
33
+ serviceExternalId = await app_client_js_1.default.createService();
34
+ if (serviceExternalId === undefined) {
35
+ console.error('Service creation failed');
36
+ return;
37
+ }
38
+ }
39
+ else {
40
+ serviceExternalId = serviceId;
41
+ }
42
+ if (serviceExternalId === undefined) {
43
+ throw new Error('Service external ID is undefined, this should be impossible');
44
+ }
45
+ const account = await app_client_js_1.default.createAccountInServiceWithEmailCollectionMode(serviceExternalId, 'MANDATORY');
46
+ if (account === undefined) {
47
+ console.error('Failed to create a fully set up account');
48
+ return;
49
+ }
50
+ console.log(account);
51
+ }
52
+ exports.default = accountHandler;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handler = exports.builder = exports.desc = exports.command = void 0;
7
+ const node_child_process_1 = require("node:child_process");
8
+ const app_client_js_1 = __importDefault(require("../app_client/app_client.js"));
9
+ const pay_local_cluster_js_1 = require("../config/pay_local_cluster.js");
10
+ const standardContent_1 = require("../../../core/standardContent");
11
+ exports.command = 'browse <service>';
12
+ exports.desc = 'Browse to local service';
13
+ const builder = (yargs) => {
14
+ return yargs
15
+ .usage(`$0 local browse <service> [--proxy]\n\n${exports.desc}`)
16
+ .positional('service', {
17
+ type: 'string',
18
+ description: 'service'
19
+ })
20
+ .option('proxy', {
21
+ type: 'boolean',
22
+ default: false,
23
+ description: 'Opens the service via the local proxy for the service'
24
+ });
25
+ };
26
+ exports.builder = builder;
27
+ exports.handler = browseHandler;
28
+ async function browseHandler(argv) {
29
+ await (0, standardContent_1.showHeader)();
30
+ const service = argv.service;
31
+ const proxy = argv.proxy;
32
+ const servicesConfig = (0, pay_local_cluster_js_1.loadServicesConfig)();
33
+ if (!(service in servicesConfig)) {
34
+ console.error(`The service specified (${service}) was not defined in the service_config.yaml file`);
35
+ return;
36
+ }
37
+ const serviceConfig = servicesConfig[service];
38
+ const url = app_client_js_1.default.externalUrlFor(service, '/', proxy);
39
+ (0, node_child_process_1.spawn)('open', [url]);
40
+ if (await app_client_js_1.default.isHealthy(serviceConfig.name)) {
41
+ console.log(`📋 “${url}” opened`);
42
+ }
43
+ else {
44
+ console.error(`❌ “${url}” opened, however the app did not respond successfully to ${url}/healthcheck`);
45
+ }
46
+ }
47
+ exports.default = browseHandler;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handler = exports.builder = exports.desc = exports.command = void 0;
4
+ const node_child_process_1 = require("node:child_process");
5
+ const pay_local_cluster_js_1 = require("../config/pay_local_cluster.js");
6
+ const standardContent_1 = require("../../../core/standardContent");
7
+ exports.command = 'db <app_name>';
8
+ exports.desc = 'Connect to <app_name> database';
9
+ const builder = (yargs) => {
10
+ return yargs
11
+ .usage(`$0 local db <app_name> [--docker]\n\n${exports.desc}`)
12
+ .positional('app_name', {
13
+ type: 'string',
14
+ description: 'service'
15
+ })
16
+ .option('docker', {
17
+ type: 'boolean',
18
+ default: false,
19
+ description: 'Launch psql inside the apps database container (no psql history)'
20
+ });
21
+ };
22
+ exports.builder = builder;
23
+ exports.handler = dbHandler;
24
+ async function dbHandler(argv) {
25
+ await (0, standardContent_1.showHeader)();
26
+ const service = argv.app_name;
27
+ const docker = argv.docker;
28
+ const servicesConfig = (0, pay_local_cluster_js_1.loadServicesConfig)();
29
+ if (!(service in servicesConfig)) {
30
+ console.error(`The service specified (${service}) was not defined in the service_config.yaml file`);
31
+ return;
32
+ }
33
+ const serviceConfig = servicesConfig[service];
34
+ if (!serviceConfig.db) {
35
+ console.error(`The service specified (${serviceConfig.name}) does not have a database`);
36
+ return;
37
+ }
38
+ if (docker) {
39
+ launchPsqlInDocker(serviceConfig);
40
+ }
41
+ else if (!psqlAvailable()) {
42
+ console.warn('PSQL installation not found locally.');
43
+ launchPsqlInDocker(serviceConfig);
44
+ }
45
+ else {
46
+ launchPsql(serviceConfig);
47
+ }
48
+ }
49
+ exports.default = dbHandler;
50
+ function psqlAvailable() {
51
+ const psqlCheck = (0, node_child_process_1.spawnSync)('command', ['-v', 'psql'], { shell: true });
52
+ if (psqlCheck.status === 0) {
53
+ return true;
54
+ }
55
+ return false;
56
+ }
57
+ function launchPsqlInDocker(serviceConfig) {
58
+ console.log('Running psql in running app db container.');
59
+ console.log('Note: This means you wont have a psql history, and one will not survive restarts of pay local');
60
+ (0, node_child_process_1.spawn)('docker', [
61
+ 'exec',
62
+ '-e', 'PGPASSWORD=mysecretpassword', // pragma: allowlist secret
63
+ '-e', 'PGSSLMODE=disable',
64
+ '-ti',
65
+ `${serviceConfig.name}_db`,
66
+ 'psql',
67
+ '--host', `${serviceConfig.name}_db`,
68
+ '--user', serviceConfig.name,
69
+ '--dbname', serviceConfig.name
70
+ ], { stdio: 'inherit', shell: true });
71
+ }
72
+ function launchPsql(serviceConfig) {
73
+ if (serviceConfig.db_port === undefined) {
74
+ throw new Error(`Service config for ${serviceConfig.name} is missing db_port specification`);
75
+ }
76
+ (0, node_child_process_1.spawn)('psql', [
77
+ '--host', '127.0.0.1',
78
+ '--port', `${serviceConfig.db_port}`,
79
+ '--user', serviceConfig.name,
80
+ '--dbname', serviceConfig.name
81
+ ], {
82
+ stdio: 'inherit',
83
+ shell: true,
84
+ env: {
85
+ ...process.env,
86
+ PGPASSWORD: 'mysecretpassword', // pragma: allowlist secret
87
+ PGSSLMODE: 'disable'
88
+ }
89
+ });
90
+ }
@@ -3,34 +3,50 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.composeFileToDown = exports.ENVIRONMENT_OVERRIDES_PATH = exports.DOCKER_COMPOSE_SERVICES_CONFIG_PATH = exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = void 0;
6
+ exports.composeFileToDown = exports.handler = exports.builder = exports.desc = exports.command = exports.ENVIRONMENT_OVERRIDES_PATH = exports.DOCKER_COMPOSE_SERVICES_CONFIG_PATH = exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = void 0;
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
8
  const node_fs_1 = __importDefault(require("node:fs"));
9
9
  const configs_js_1 = require("../../../util/configs.js");
10
10
  const last_up_record_js_1 = require("../config/last_up_record.js");
11
11
  const docker_compose_controller_js_1 = __importDefault(require("../docker_compose_controller.js"));
12
+ const pay_local_cluster_js_1 = require("../config/pay_local_cluster.js");
13
+ const standardContent_1 = require("../../../core/standardContent");
12
14
  exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = node_path_1.default.join('local', 'docker-compose', 'rendered-templates');
13
15
  exports.DOCKER_COMPOSE_SERVICES_CONFIG_PATH = node_path_1.default.join('local', 'docker-compose', 'default-configs-DO-NOT-EDIT');
14
16
  exports.ENVIRONMENT_OVERRIDES_PATH = node_path_1.default.join('local', 'environment-overrides');
15
- async function DownHandler(options) {
17
+ exports.command = 'down';
18
+ exports.desc = 'Bring down a cluster';
19
+ const builder = (yargs) => {
20
+ return yargs
21
+ .usage(`$0 local down [--cluster <cluster>]\n\n${exports.desc}`)
22
+ .option('cluster', {
23
+ type: 'string',
24
+ description: 'Cluster to bring down',
25
+ choices: pay_local_cluster_js_1.CLUSTERS
26
+ });
27
+ };
28
+ exports.builder = builder;
29
+ exports.handler = downHandler;
30
+ async function downHandler(argv) {
31
+ await (0, standardContent_1.showHeader)();
32
+ const { cluster } = argv;
16
33
  const renderedTempaltesPath = (0, configs_js_1.ensureConfigDirectory)(exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH);
17
- const args = parseArguments(options);
18
- const composeFilePath = composeFileToDown(args, renderedTempaltesPath);
34
+ const composeFilePath = composeFileToDown(cluster, renderedTempaltesPath);
19
35
  const composeFileName = node_path_1.default.basename(composeFilePath);
20
36
  const clusterToDown = composeFileName.substring(0, composeFileName.lastIndexOf('.yaml'));
21
37
  console.log(`Bringing down cluster ${clusterToDown}`);
22
38
  docker_compose_controller_js_1.default.down(composeFilePath);
23
39
  }
24
- exports.default = DownHandler;
25
- function composeFileToDown(downOptions, renderedTemplatesPath) {
26
- if (downOptions.cluster !== undefined) {
27
- const clusterFilePath = node_path_1.default.resolve(renderedTemplatesPath, `${downOptions.cluster}.yaml`);
40
+ exports.default = downHandler;
41
+ function composeFileToDown(cluster, renderedTemplatesPath) {
42
+ if (cluster !== undefined) {
43
+ const clusterFilePath = node_path_1.default.resolve(renderedTemplatesPath, `${cluster}.yaml`);
28
44
  if (node_fs_1.default.existsSync(clusterFilePath)) {
29
45
  return clusterFilePath;
30
46
  }
31
- throw new Error(`Cannot bring down cluster '${downOptions.cluster}' since it does not have a rendered docker-compose template in ${renderedTemplatesPath}.\n` +
47
+ throw new Error(`Cannot bring down cluster '${cluster}' since it does not have a rendered docker-compose template in ${renderedTemplatesPath}.\n` +
32
48
  '\n' +
33
- `Perhaps you don't have a cluster running, or the cluster that is running isn't ${downOptions.cluster}\n`);
49
+ `Perhaps you don't have a cluster running, or the cluster that is running isn't ${cluster}\n`);
34
50
  }
35
51
  const mostRecentUpFile = (0, last_up_record_js_1.getLastUp)(renderedTemplatesPath);
36
52
  if (mostRecentUpFile !== undefined) {
@@ -49,8 +65,3 @@ function composeFileToDown(downOptions, renderedTemplatesPath) {
49
65
  'Perhaps you do not have a running cluster, or you need to `pay local down --cluster <cluster>` specifying the last cluster you launched\n');
50
66
  }
51
67
  exports.composeFileToDown = composeFileToDown;
52
- function parseArguments(_options) {
53
- return {
54
- cluster: 'card'
55
- };
56
- }
@@ -3,26 +3,32 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ENVIRONMENT_OVERRIDES_PATH = exports.DOCKER_COMPOSE_SERVICES_CONFIG_PATH = exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = void 0;
6
+ exports.handler = exports.desc = exports.command = exports.ENVIRONMENT_OVERRIDES_PATH = exports.DOCKER_COMPOSE_SERVICES_CONFIG_PATH = exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = void 0;
7
7
  const up_js_1 = __importDefault(require("./up.js"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const docker_compose_controller_js_1 = __importDefault(require("../docker_compose_controller.js"));
10
+ const standardContent_1 = require("../../../core/standardContent");
10
11
  exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = node_path_1.default.join('local', 'docker-compose', 'rendered-templates');
11
12
  exports.DOCKER_COMPOSE_SERVICES_CONFIG_PATH = node_path_1.default.join('local', 'docker-compose', 'default-configs-DO-NOT-EDIT');
12
13
  exports.ENVIRONMENT_OVERRIDES_PATH = node_path_1.default.join('local', 'environment-overrides');
13
- async function NukeHandler() {
14
+ exports.command = 'nuke';
15
+ exports.desc = 'Kill and completely destroy all containers previously started by pay local';
16
+ exports.handler = nukeHandler;
17
+ async function nukeHandler(argv) {
18
+ await (0, standardContent_1.showHeader)();
14
19
  const upOptions = {
15
20
  cluster: 'nuke',
16
21
  proxy: true,
17
- with_egress_proxy: true,
22
+ withEgressProxy: true,
18
23
  apps: [],
19
24
  local: [],
20
25
  rebuild: false,
21
26
  pull: false,
22
- mount_local_node_apps: false
27
+ mountLocalNodeApps: false,
28
+ mountPayJSCommons: false
23
29
  };
24
30
  const renderedTemplatePath = await (0, up_js_1.default)(upOptions, true);
25
31
  console.log('Nuking cluster');
26
32
  docker_compose_controller_js_1.default.nuke(renderedTemplatePath);
27
33
  }
28
- exports.default = NukeHandler;
34
+ exports.default = nukeHandler;
@@ -1,27 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handler = exports.builder = exports.desc = exports.command = void 0;
3
4
  const node_child_process_1 = require("node:child_process");
4
5
  const totp_generator_1 = require("totp-generator");
5
- async function OTPHandler(options) {
6
- const args = parseArguments(options);
7
- const { otp } = totp_generator_1.TOTP.generate(args.secret);
6
+ const standardContent_1 = require("../../../core/standardContent");
7
+ exports.command = 'opt <key>';
8
+ exports.desc = 'Create otp code';
9
+ const builder = (yargs) => {
10
+ return yargs.positional('key', {
11
+ type: 'string',
12
+ description: 'otp key'
13
+ });
14
+ };
15
+ exports.builder = builder;
16
+ exports.handler = otpHandler;
17
+ async function otpHandler(argv) {
18
+ await (0, standardContent_1.showHeader)();
19
+ const { otp } = totp_generator_1.TOTP.generate(argv.key);
8
20
  console.log(otp);
9
21
  copyToClipboard(otp);
10
22
  console.log(`📋 “${otp}” copied to clipboard`);
11
23
  }
12
- exports.default = OTPHandler;
13
- function parseArguments(options) {
14
- if (options.length !== 1) {
15
- help();
16
- throw new Error('No key specified');
17
- }
18
- return { secret: options[0].trimEnd() };
19
- }
24
+ exports.default = otpHandler;
20
25
  function copyToClipboard(otp) {
21
26
  const proc = (0, node_child_process_1.spawn)('pbcopy');
22
27
  proc.stdin.write(otp);
23
28
  proc.stdin.end();
24
29
  }
25
- function help() {
26
- console.log('Usage: pay local otp <otp_secret_key>');
27
- }
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handler = exports.builder = exports.desc = exports.command = void 0;
7
+ const node_child_process_1 = require("node:child_process");
8
+ const app_client_js_1 = __importDefault(require("../app_client/app_client.js"));
9
+ const standardContent_1 = require("../../../core/standardContent");
10
+ exports.command = 'payment';
11
+ exports.desc = 'Create a payment';
12
+ const builder = (yargs) => {
13
+ return yargs
14
+ .usage(`$0 local payment [--api-key <api-key>] [--email-collection-mode <email-collection-mode>]\n\n${exports.desc}`)
15
+ .option('api-key', {
16
+ type: 'string',
17
+ description: 'API Key'
18
+ }).option('email-collection-mode', {
19
+ type: 'string',
20
+ default: 'MANDATORY',
21
+ choices: ['MANDATORY', 'OPTIONAL', 'OFF'],
22
+ description: 'Email collection mode to use'
23
+ });
24
+ };
25
+ exports.builder = builder;
26
+ exports.handler = paymentHandler;
27
+ async function paymentHandler(argv) {
28
+ await (0, standardContent_1.showHeader)();
29
+ let apiKey = argv.apiKey;
30
+ if (await app_client_js_1.default.isUnhealthy('connector')) {
31
+ console.error('The connector service is unhealthy, so a payment cannot be created');
32
+ return;
33
+ }
34
+ if (await app_client_js_1.default.isUnhealthy('publicapi')) {
35
+ console.error('The publicapi service is unhealthy, so a payment cannot be created');
36
+ return;
37
+ }
38
+ if (apiKey === undefined) {
39
+ console.warn('👔 Creating gateway account and service');
40
+ console.warn();
41
+ if (await app_client_js_1.default.isUnhealthy('adminusers')) {
42
+ console.error('The adminusers service is unhealthy, so a gateway account cannot be created to enable a payment to be created');
43
+ return;
44
+ }
45
+ const serviceExternalID = await app_client_js_1.default.createService();
46
+ if (serviceExternalID === undefined) {
47
+ console.error('Unable to create a service');
48
+ return;
49
+ }
50
+ const account = await app_client_js_1.default.createAccountInServiceWithEmailCollectionMode(serviceExternalID, argv.emailCollectionMode);
51
+ if (account === undefined) {
52
+ console.error('Failed to create a fully set up account');
53
+ return;
54
+ }
55
+ const createTokenResult = await app_client_js_1.default.createToken(account.gateway_account_id);
56
+ if (createTokenResult === undefined) {
57
+ console.error('Failed to create an api token');
58
+ return;
59
+ }
60
+ apiKey = createTokenResult;
61
+ console.warn(`🆔 Gateway account ID: ${account.gateway_account_id}`);
62
+ console.warn(`💁 Service ID: ${serviceExternalID}`);
63
+ console.warn();
64
+ }
65
+ const createPaymentResult = await app_client_js_1.default.createPayment(apiKey);
66
+ if (createPaymentResult === undefined) {
67
+ console.error('Failed to create a payment');
68
+ return;
69
+ }
70
+ console.warn(`💷 Payment ID: ${createPaymentResult.payment_id}`);
71
+ console.warn(`🎫 API token: ${apiKey}`);
72
+ console.warn();
73
+ const nextUrl = createPaymentResult._links.next_url?.href;
74
+ if (nextUrl === undefined) {
75
+ console.error('The response from creating the payment did not include a next_url link');
76
+ return;
77
+ }
78
+ console.log(`Opening next_url (${nextUrl} in your browser`);
79
+ (0, node_child_process_1.spawn)('open', [nextUrl]);
80
+ }
81
+ exports.default = paymentHandler;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handler = exports.builder = exports.desc = exports.command = void 0;
7
+ const node_child_process_1 = __importDefault(require("node:child_process"));
8
+ const app_client_js_1 = __importDefault(require("../app_client/app_client.js"));
9
+ const standardContent_1 = require("../../../core/standardContent");
10
+ exports.command = 'paymentlink';
11
+ exports.desc = 'Create a payment link';
12
+ const builder = (yargs) => {
13
+ return yargs
14
+ .usage(`$0 local paymentlink --api-key <api-key>\n\n${exports.desc}`)
15
+ .option('api-key', {
16
+ demandOption: true,
17
+ type: 'string',
18
+ description: 'API Key'
19
+ });
20
+ };
21
+ exports.builder = builder;
22
+ exports.handler = paymentLinkHandler;
23
+ async function paymentLinkHandler(argv) {
24
+ await (0, standardContent_1.showHeader)();
25
+ const apiKey = argv.apiKey;
26
+ if (await app_client_js_1.default.isUnhealthy('products')) {
27
+ console.error('The products service is unhealthy, so a payment link cannot be created');
28
+ return;
29
+ }
30
+ else if (await app_client_js_1.default.isUnhealthy('products-ui')) {
31
+ console.error('The products-ui service is unhealthy, so a payment link cannot be created');
32
+ return;
33
+ }
34
+ const paymentLinks = await app_client_js_1.default.createPaymentLink(apiKey);
35
+ if (paymentLinks === undefined) {
36
+ console.error('Payment link creation failed');
37
+ return;
38
+ }
39
+ paymentLinks.forEach((link) => { console.log(`${link.method} ${link.rel}: ${link.href}`); });
40
+ const payLink = paymentLinks.find((link) => link.rel === 'pay');
41
+ if (payLink === undefined) {
42
+ console.error('The response to create a payment link did not include a link with the rel of "pay"');
43
+ return;
44
+ }
45
+ node_child_process_1.default.spawn('open', [payLink.href]);
46
+ }
47
+ exports.default = paymentLinkHandler;
@@ -3,33 +3,36 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = void 0;
6
+ exports.handler = exports.builder = exports.desc = exports.command = exports.DOCKER_COMPOSE_RENDERED_TEMPLATES_PATH = void 0;
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
8
  const configs_js_1 = require("../../../util/configs.js");
9
9
  const last_up_record_js_1 = require("../config/last_up_record.js");
10
10
  const docker_compose_controller_js_1 = __importDefault(require("../docker_compose_controller.js"));
11
- exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = node_path_1.default.join('local', 'docker-compose', 'rendered-templates');
12
- async function DownHandler(options) {
13
- const renderedTempaltesPath = (0, configs_js_1.ensureConfigDirectory)(exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH);
14
- const args = parseArguments(options);
11
+ const standardContent_1 = require("../../../core/standardContent");
12
+ exports.DOCKER_COMPOSE_RENDERED_TEMPLATES_PATH = node_path_1.default.join('local', 'docker-compose', 'rendered-templates');
13
+ exports.command = 'restart <app>';
14
+ exports.desc = 'Restart a container and waits for it to be healthy';
15
+ const builder = (yargs) => {
16
+ return yargs
17
+ .usage(`$0 local restart <app>\n\n${exports.desc}`)
18
+ .positional('app', {
19
+ type: 'string',
20
+ description: 'App to restart'
21
+ });
22
+ };
23
+ exports.builder = builder;
24
+ exports.handler = restartHandler;
25
+ async function restartHandler(argv) {
26
+ await (0, standardContent_1.showHeader)();
27
+ const service = argv.app;
28
+ const renderedTempaltesPath = (0, configs_js_1.ensureConfigDirectory)(exports.DOCKER_COMPOSE_RENDERED_TEMPLATES_PATH);
15
29
  const composeFilePath = (0, last_up_record_js_1.getLastUp)(renderedTempaltesPath);
16
30
  if (composeFilePath === undefined) {
17
31
  throw new Error('Cannot find the docker-compose file for the running cluster');
18
32
  }
19
33
  const composeFileName = node_path_1.default.basename(composeFilePath);
20
34
  const clusterName = composeFileName.substring(0, composeFileName.lastIndexOf('.yaml'));
21
- console.log(`\nRestarting '${args.service} in cluster ${clusterName}`);
22
- docker_compose_controller_js_1.default.restart(composeFilePath, args.service);
23
- }
24
- exports.default = DownHandler;
25
- function parseArguments(options) {
26
- if (options.length !== 1) {
27
- throw new Error('Incorrect number of arguments, expected 1 to restart command\n' +
28
- '\n' +
29
- ' Usage: pay local restart <service>\n' +
30
- '\n');
31
- }
32
- return {
33
- service: options[0]
34
- };
35
+ console.log(`\nRestarting '${service} in cluster ${clusterName}`);
36
+ docker_compose_controller_js_1.default.restart(composeFilePath, service);
35
37
  }
38
+ exports.default = restartHandler;