@govuk-pay/cli 0.0.30 → 0.0.32

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.
Files changed (57) hide show
  1. package/package.json +4 -2
  2. package/resources/pay-local/config/localstack/init-aws.sh +70 -0
  3. package/resources/pay-local/config/postgres/docker-entrypoint-initdb.d/make_payments_databases.sql +26 -0
  4. package/resources/pay-local/config/service_config.yaml +193 -0
  5. package/resources/pay-local/config/services/adminusers.env +49 -0
  6. package/resources/pay-local/config/services/cardid.env +2 -0
  7. package/resources/pay-local/config/services/connector.env +70 -0
  8. package/resources/pay-local/config/services/demo-service.env +10 -0
  9. package/resources/pay-local/config/services/egress/squid.conf +47 -0
  10. package/resources/pay-local/config/services/frontend.env +12 -0
  11. package/resources/pay-local/config/services/java_app.env +1 -0
  12. package/resources/pay-local/config/services/ledger.env +10 -0
  13. package/resources/pay-local/config/services/products-ui.env +14 -0
  14. package/resources/pay-local/config/services/products.env +25 -0
  15. package/resources/pay-local/config/services/publicapi.env +13 -0
  16. package/resources/pay-local/config/services/publicauth.env +13 -0
  17. package/resources/pay-local/config/services/selfservice.env +21 -0
  18. package/resources/pay-local/config/services/ssl/certs/frontend-proxy.crt +18 -0
  19. package/resources/pay-local/config/services/ssl/certs/products-ui-proxy.crt +20 -0
  20. package/resources/pay-local/config/services/ssl/certs/publicapi-proxy.crt +18 -0
  21. package/resources/pay-local/config/services/ssl/certs/selfservice-proxy.crt +20 -0
  22. package/resources/pay-local/config/services/ssl/certs/stubs-proxy.crt +18 -0
  23. package/resources/pay-local/config/services/ssl/keys/frontend-proxy.key +28 -0
  24. package/resources/pay-local/config/services/ssl/keys/products-ui-proxy.key +28 -0
  25. package/resources/pay-local/config/services/ssl/keys/publicapi-proxy.key +28 -0
  26. package/resources/pay-local/config/services/ssl/keys/selfservice-proxy.key +28 -0
  27. package/resources/pay-local/config/services/ssl/keys/stubs-proxy.key +28 -0
  28. package/resources/pay-local/config/services/ssl/make-selfsigned.sh +2 -0
  29. package/resources/pay-local/config/services/stubs.env +12 -0
  30. package/resources/pay-local/config/services/toolbox.env +6 -0
  31. package/resources/pay-local/config/services/webhooks.env +9 -0
  32. package/resources/pay-local/templates/docker-compose.hbs +276 -0
  33. package/resources/usageDetails.txt +1 -0
  34. package/src/commands/local/app_client/app_client.js +232 -0
  35. package/src/commands/local/app_client/fetch_wrapper.js +106 -0
  36. package/src/commands/local/config/default_config_setup.js +13 -0
  37. package/src/commands/local/config/last_up_record.js +50 -0
  38. package/src/commands/local/config/pay_local_cluster.js +225 -0
  39. package/src/commands/local/config/renderer.js +46 -0
  40. package/src/commands/local/docker_compose_controller.js +24 -0
  41. package/src/commands/local/subcommands/account.js +51 -0
  42. package/src/commands/local/subcommands/browse.js +39 -0
  43. package/src/commands/local/subcommands/db.js +82 -0
  44. package/src/commands/local/subcommands/down.js +56 -0
  45. package/src/commands/local/subcommands/nuke.js +28 -0
  46. package/src/commands/local/subcommands/otp.js +27 -0
  47. package/src/commands/local/subcommands/payment.js +68 -0
  48. package/src/commands/local/subcommands/paymentlink.js +41 -0
  49. package/src/commands/local/subcommands/restart.js +35 -0
  50. package/src/commands/local/subcommands/token.js +66 -0
  51. package/src/commands/local/subcommands/up.js +55 -0
  52. package/src/commands/local/subcommands/url.js +44 -0
  53. package/src/commands/local/subcommands/user.js +91 -0
  54. package/src/commands/local.js +136 -0
  55. package/src/core/commandRouter.js +4 -0
  56. package/src/util/configs.js +47 -0
  57. package/src/util/md5.js +16 -0
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_child_process_1 = require("node:child_process");
4
+ const dockerComposeController = {
5
+ up(composeFilePath) {
6
+ (0, node_child_process_1.spawnSync)('docker', ['compose', '--file', composeFilePath, 'up', '--detach', '--wait'], { shell: true, stdio: 'inherit' });
7
+ },
8
+ down(composeFilePath) {
9
+ (0, node_child_process_1.spawnSync)('docker', ['compose', '--file', composeFilePath, 'down'], { shell: true, stdio: 'inherit' });
10
+ },
11
+ nuke(composeFilePath) {
12
+ (0, node_child_process_1.spawnSync)('docker', ['compose', '--file', composeFilePath, 'down', '--volumes'], { shell: true, stdio: 'inherit' });
13
+ },
14
+ pull(composeFilePath) {
15
+ (0, node_child_process_1.spawnSync)('docker', ['compose', '--file', composeFilePath, 'pull'], { shell: true, stdio: 'inherit' });
16
+ },
17
+ restart(composeFilePath, service) {
18
+ (0, node_child_process_1.spawnSync)('docker', ['compose', '--file', composeFilePath, 'restart', service], { shell: true, stdio: 'inherit' });
19
+ },
20
+ build(composeFilePath) {
21
+ (0, node_child_process_1.spawnSync)('docker', ['compose', '--file', composeFilePath, 'build'], { shell: true, stdio: 'inherit' });
22
+ }
23
+ };
24
+ exports.default = dockerComposeController;
@@ -0,0 +1,51 @@
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
+ const app_client_js_1 = __importDefault(require("../app_client/app_client.js"));
7
+ async function AccountHandler(options) {
8
+ const args = parseArguments(options);
9
+ if (await app_client_js_1.default.isUnhealthy('adminusers')) {
10
+ console.error('The adminusers service is unhealthy, so an account cannot be created');
11
+ return;
12
+ }
13
+ if (await app_client_js_1.default.isUnhealthy('connector')) {
14
+ console.error('The connector service is unhealthy, so an account cannot be created');
15
+ return;
16
+ }
17
+ let serviceExternalID;
18
+ if (args.serviceID === undefined) {
19
+ serviceExternalID = await app_client_js_1.default.createService();
20
+ if (serviceExternalID === undefined) {
21
+ console.error('Service creation failed');
22
+ return;
23
+ }
24
+ }
25
+ else {
26
+ serviceExternalID = args.serviceID;
27
+ }
28
+ if (serviceExternalID === undefined) {
29
+ throw new Error('Service external ID is undefined, this should be impossible');
30
+ }
31
+ const account = await app_client_js_1.default.createAccountInServiceWithEmailCollectionMode(serviceExternalID, 'MANDATORY');
32
+ if (account === undefined) {
33
+ console.error('Failed to create a fully set up account');
34
+ return;
35
+ }
36
+ console.log(account);
37
+ }
38
+ exports.default = AccountHandler;
39
+ function parseArguments(options) {
40
+ if (options.length === 0) {
41
+ return {};
42
+ }
43
+ if (options.length > 1) {
44
+ help();
45
+ throw new Error('Too many arguments');
46
+ }
47
+ return { serviceID: options[0] };
48
+ }
49
+ function help() {
50
+ console.log('Usage: pay local account [service_id]>');
51
+ }
@@ -0,0 +1,39 @@
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
+ const node_child_process_1 = require("node:child_process");
7
+ const app_client_js_1 = __importDefault(require("../app_client/app_client.js"));
8
+ const pay_local_cluster_js_1 = require("../config/pay_local_cluster.js");
9
+ async function BrowseHandler(options) {
10
+ const args = parseArguments(options);
11
+ const servicesConfig = (0, pay_local_cluster_js_1.loadServicesConfig)();
12
+ if (!(args.service in servicesConfig)) {
13
+ console.error(`The service specified (${args.service}) was not defined in the service_config.yaml file`);
14
+ return;
15
+ }
16
+ const serviceConfig = servicesConfig[args.service];
17
+ const url = app_client_js_1.default.externalUrlFor(args.service, '/', args.proxy);
18
+ (0, node_child_process_1.spawn)('open', [url]);
19
+ if (await app_client_js_1.default.isHealthy(serviceConfig.name)) {
20
+ console.log(`📋 “${url}” opened`);
21
+ }
22
+ else {
23
+ console.error(`❌ “${url}” opened, however the app did not respond successfully to ${url}/healthcheck`);
24
+ }
25
+ }
26
+ exports.default = BrowseHandler;
27
+ function help() {
28
+ console.log('Usage: pay local browse <service>');
29
+ }
30
+ function parseArguments(options) {
31
+ if (options.length !== 1) {
32
+ help();
33
+ throw new Error('No service specified');
34
+ }
35
+ return {
36
+ service: options[0],
37
+ proxy: true
38
+ };
39
+ }
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_child_process_1 = require("node:child_process");
4
+ const pay_local_cluster_js_1 = require("../config/pay_local_cluster.js");
5
+ async function DBHandler(options) {
6
+ const args = parseArguments(options);
7
+ const servicesConfig = (0, pay_local_cluster_js_1.loadServicesConfig)();
8
+ if (!(args.service in servicesConfig)) {
9
+ console.error(`The service specified (${args.service}) was not defined in the service_config.yaml file`);
10
+ return;
11
+ }
12
+ const serviceConfig = servicesConfig[args.service];
13
+ if (!serviceConfig.db) {
14
+ console.error(`The service specified (${serviceConfig.name}) does not have a database`);
15
+ return;
16
+ }
17
+ if (args.docker) {
18
+ launchPsqlInDocker(serviceConfig);
19
+ }
20
+ else if (!psqlAvailable()) {
21
+ console.warn('PSQL installation not found locally.');
22
+ launchPsqlInDocker(serviceConfig);
23
+ }
24
+ else {
25
+ launchPsql(serviceConfig);
26
+ }
27
+ }
28
+ exports.default = DBHandler;
29
+ function psqlAvailable() {
30
+ const psqlCheck = (0, node_child_process_1.spawnSync)('command', ['-v', 'psql'], { shell: true });
31
+ if (psqlCheck.status === 0) {
32
+ return true;
33
+ }
34
+ return false;
35
+ }
36
+ function launchPsqlInDocker(serviceConfig) {
37
+ console.log('Running psql in running app db container.');
38
+ console.log('Note: This means you wont have a psql history, and one will not survive restarts of pay local');
39
+ (0, node_child_process_1.spawn)('docker', [
40
+ 'exec',
41
+ '-e', 'PGPASSWORD=mysecretpassword', // pragma: allowlist secret
42
+ '-e', 'PGSSLMODE=disable',
43
+ '-ti',
44
+ `${serviceConfig.name}_db`,
45
+ 'psql',
46
+ '--host', `${serviceConfig.name}_db`,
47
+ '--user', serviceConfig.name,
48
+ '--dbname', serviceConfig.name
49
+ ], { stdio: 'inherit', shell: true });
50
+ }
51
+ function launchPsql(serviceConfig) {
52
+ if (serviceConfig.db_port === undefined) {
53
+ throw new Error(`Service config for ${serviceConfig.name} is missing db_port specification`);
54
+ }
55
+ (0, node_child_process_1.spawn)('psql', [
56
+ '--host', '127.0.0.1',
57
+ '--port', `${serviceConfig.db_port}`,
58
+ '--user', serviceConfig.name,
59
+ '--dbname', serviceConfig.name
60
+ ], {
61
+ stdio: 'inherit',
62
+ shell: true,
63
+ env: {
64
+ ...process.env,
65
+ PGPASSWORD: 'mysecretpassword', // pragma: allowlist secret
66
+ PGSSLMODE: 'disable'
67
+ }
68
+ });
69
+ }
70
+ function help() {
71
+ console.log('Usage: pay local db <service> [--docker]');
72
+ }
73
+ function parseArguments(options) {
74
+ if (options.length !== 1) {
75
+ help();
76
+ throw new Error('No service specified');
77
+ }
78
+ return {
79
+ service: options[0],
80
+ docker: false
81
+ };
82
+ }
@@ -0,0 +1,56 @@
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.composeFileToDown = exports.ENVIRONMENT_OVERRIDES_PATH = exports.DOCKER_COMPOSE_SERVICES_CONFIG_PATH = exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const node_fs_1 = __importDefault(require("node:fs"));
9
+ const configs_js_1 = require("../../../util/configs.js");
10
+ const last_up_record_js_1 = require("../config/last_up_record.js");
11
+ const docker_compose_controller_js_1 = __importDefault(require("../docker_compose_controller.js"));
12
+ exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = node_path_1.default.join('local', 'docker-compose', 'rendered-templates');
13
+ exports.DOCKER_COMPOSE_SERVICES_CONFIG_PATH = node_path_1.default.join('local', 'docker-compose', 'default-configs-DO-NOT-EDIT');
14
+ exports.ENVIRONMENT_OVERRIDES_PATH = node_path_1.default.join('local', 'environment-overrides');
15
+ async function DownHandler(options) {
16
+ const renderedTempaltesPath = (0, configs_js_1.ensureConfigDirectory)(exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH);
17
+ const args = parseArguments(options);
18
+ const composeFilePath = composeFileToDown(args, renderedTempaltesPath);
19
+ const composeFileName = node_path_1.default.basename(composeFilePath);
20
+ const clusterToDown = composeFileName.substring(0, composeFileName.lastIndexOf('.yaml'));
21
+ console.log(`Bringing down cluster ${clusterToDown}`);
22
+ docker_compose_controller_js_1.default.down(composeFilePath);
23
+ }
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`);
28
+ if (node_fs_1.default.existsSync(clusterFilePath)) {
29
+ return clusterFilePath;
30
+ }
31
+ throw new Error(`Cannot bring down cluster '${downOptions.cluster}' since it does not have a rendered docker-compose template in ${renderedTemplatesPath}.\n` +
32
+ '\n' +
33
+ `Perhaps you don't have a cluster running, or the cluster that is running isn't ${downOptions.cluster}\n`);
34
+ }
35
+ const mostRecentUpFile = (0, last_up_record_js_1.getLastUp)(renderedTemplatesPath);
36
+ if (mostRecentUpFile !== undefined) {
37
+ return mostRecentUpFile;
38
+ }
39
+ const defaultDownFile = node_path_1.default.join(renderedTemplatesPath, 'all.yaml');
40
+ if (node_fs_1.default.existsSync(defaultDownFile)) {
41
+ return defaultDownFile;
42
+ }
43
+ throw new Error('Could not determine which cluster to bring down.\n' +
44
+ '\n' +
45
+ ' * You did not specify a cluster with --cluster.\n' +
46
+ " * There is no valid record of a most recent 'up'\n" +
47
+ " * The 'all' cluster rendered docker-compose.yaml file does not exist.\n" +
48
+ '\n' +
49
+ '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
+ }
51
+ exports.composeFileToDown = composeFileToDown;
52
+ function parseArguments(_options) {
53
+ return {
54
+ cluster: 'card'
55
+ };
56
+ }
@@ -0,0 +1,28 @@
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.ENVIRONMENT_OVERRIDES_PATH = exports.DOCKER_COMPOSE_SERVICES_CONFIG_PATH = exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = void 0;
7
+ const up_js_1 = __importDefault(require("./up.js"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const docker_compose_controller_js_1 = __importDefault(require("../docker_compose_controller.js"));
10
+ exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = node_path_1.default.join('local', 'docker-compose', 'rendered-templates');
11
+ exports.DOCKER_COMPOSE_SERVICES_CONFIG_PATH = node_path_1.default.join('local', 'docker-compose', 'default-configs-DO-NOT-EDIT');
12
+ exports.ENVIRONMENT_OVERRIDES_PATH = node_path_1.default.join('local', 'environment-overrides');
13
+ async function NukeHandler() {
14
+ const upOptions = {
15
+ cluster: 'nuke',
16
+ proxy: true,
17
+ with_egress_proxy: true,
18
+ apps: [],
19
+ local: [],
20
+ rebuild: false,
21
+ pull: false,
22
+ mount_local_node_apps: false
23
+ };
24
+ const renderedTemplatePath = await (0, up_js_1.default)(upOptions, true);
25
+ console.log('Nuking cluster');
26
+ docker_compose_controller_js_1.default.nuke(renderedTemplatePath);
27
+ }
28
+ exports.default = NukeHandler;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_child_process_1 = require("node:child_process");
4
+ 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);
8
+ console.log(otp);
9
+ copyToClipboard(otp);
10
+ console.log(`📋 “${otp}” copied to clipboard`);
11
+ }
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
+ }
20
+ function copyToClipboard(otp) {
21
+ const proc = (0, node_child_process_1.spawn)('pbcopy');
22
+ proc.stdin.write(otp);
23
+ proc.stdin.end();
24
+ }
25
+ function help() {
26
+ console.log('Usage: pay local otp <otp_secret_key>');
27
+ }
@@ -0,0 +1,68 @@
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
+ const node_child_process_1 = require("node:child_process");
7
+ const app_client_js_1 = __importDefault(require("../app_client/app_client.js"));
8
+ async function PaymentHandler(options) {
9
+ const args = parseArguments(options);
10
+ if (await app_client_js_1.default.isUnhealthy('connector')) {
11
+ console.error('The connector service is unhealthy, so a payment cannot be created');
12
+ return;
13
+ }
14
+ if (await app_client_js_1.default.isUnhealthy('publicapi')) {
15
+ console.error('The publicapi service is unhealthy, so a payment cannot be created');
16
+ return;
17
+ }
18
+ let apiKey;
19
+ if (args.api_key === undefined) {
20
+ console.warn('👔 Creating gateway account and service');
21
+ console.warn();
22
+ if (await app_client_js_1.default.isUnhealthy('adminusers')) {
23
+ console.error('The adminusers service is unhealthy, so a gateway account cannot be created to enable a payment to be created');
24
+ return;
25
+ }
26
+ const serviceExternalID = await app_client_js_1.default.createService();
27
+ if (serviceExternalID === undefined) {
28
+ console.error('Unable to create a service');
29
+ return;
30
+ }
31
+ const account = await app_client_js_1.default.createAccountInServiceWithEmailCollectionMode(serviceExternalID, args.email_collection_mode === undefined ? 'MANDATORY' : args.email_collection_mode);
32
+ if (account === undefined) {
33
+ console.error('Failed to create a fully set up account');
34
+ return;
35
+ }
36
+ const createTokenResult = await app_client_js_1.default.createToken(account.gateway_account_id);
37
+ if (createTokenResult === undefined) {
38
+ console.error('Failed to create an api token');
39
+ return;
40
+ }
41
+ apiKey = createTokenResult;
42
+ console.warn(`🆔 Gateway account ID: ${account.gateway_account_id}`);
43
+ console.warn(`💁 Service ID: ${serviceExternalID}`);
44
+ console.warn();
45
+ }
46
+ else {
47
+ apiKey = args.api_key;
48
+ }
49
+ const createPaymentResult = await app_client_js_1.default.createPayment(apiKey);
50
+ if (createPaymentResult === undefined) {
51
+ console.error('Failed to create a payment');
52
+ return;
53
+ }
54
+ console.warn(`💷 Payment ID: ${createPaymentResult.payment_id}`);
55
+ console.warn(`🎫 API token: ${apiKey}`);
56
+ console.warn();
57
+ const nextUrl = createPaymentResult._links.next_url?.href;
58
+ if (nextUrl === undefined) {
59
+ console.error('The response from creating the payment did not include a next_url link');
60
+ return;
61
+ }
62
+ console.log(`Opening next_url (${nextUrl} in your browser`);
63
+ (0, node_child_process_1.spawn)('open', [nextUrl]);
64
+ }
65
+ exports.default = PaymentHandler;
66
+ function parseArguments(_options) {
67
+ return {};
68
+ }
@@ -0,0 +1,41 @@
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
+ const node_child_process_1 = __importDefault(require("node:child_process"));
7
+ const app_client_js_1 = __importDefault(require("../app_client/app_client.js"));
8
+ async function PaymentLinkHandler(options) {
9
+ const args = parseArguments(options);
10
+ if (await app_client_js_1.default.isUnhealthy('products')) {
11
+ console.error('The products service is unhealthy, so a payment link cannot be created');
12
+ return;
13
+ }
14
+ else if (await app_client_js_1.default.isUnhealthy('products-ui')) {
15
+ console.error('The products-ui service is unhealthy, so a payment link cannot be created');
16
+ return;
17
+ }
18
+ const paymentLinks = await app_client_js_1.default.createPaymentLink(args.apiKey);
19
+ if (paymentLinks === undefined) {
20
+ console.error('Payment link creation failed');
21
+ return;
22
+ }
23
+ paymentLinks.forEach((link) => { console.log(`${link.method} ${link.rel}: ${link.href}`); });
24
+ const payLink = paymentLinks.find((link) => link.rel === 'pay');
25
+ if (payLink === undefined) {
26
+ console.error('The response to create a payment link did not include a link with the rel of "pay"');
27
+ return;
28
+ }
29
+ node_child_process_1.default.spawn('open', [payLink.href]);
30
+ }
31
+ exports.default = PaymentLinkHandler;
32
+ function parseArguments(options) {
33
+ if (options.length !== 1) {
34
+ help();
35
+ throw new Error('No key specified');
36
+ }
37
+ return { apiKey: options[0].trimEnd() };
38
+ }
39
+ function help() {
40
+ console.log('Usage: pay local paymentlink <api_key>');
41
+ }
@@ -0,0 +1,35 @@
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.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const configs_js_1 = require("../../../util/configs.js");
9
+ const last_up_record_js_1 = require("../config/last_up_record.js");
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);
15
+ const composeFilePath = (0, last_up_record_js_1.getLastUp)(renderedTempaltesPath);
16
+ if (composeFilePath === undefined) {
17
+ throw new Error('Cannot find the docker-compose file for the running cluster');
18
+ }
19
+ const composeFileName = node_path_1.default.basename(composeFilePath);
20
+ 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
+ }
@@ -0,0 +1,66 @@
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
+ const node_child_process_1 = require("node:child_process");
7
+ const app_client_js_1 = __importDefault(require("../app_client/app_client.js"));
8
+ async function TokenHandler(options) {
9
+ const args = parseArguments(options);
10
+ if (await app_client_js_1.default.isUnhealthy('publicauth')) {
11
+ console.error('The publicauth service is unhealthy, so an API token cannot be created');
12
+ return;
13
+ }
14
+ let gatewayAccountID;
15
+ if (args.gatewayAccountID === undefined) {
16
+ console.log('No gateway_account_id provided, creating service and gateway account');
17
+ if (await app_client_js_1.default.isUnhealthy('adminusers')) {
18
+ console.error('The adminusers service is unhealthy, so an API token cannot be created');
19
+ return;
20
+ }
21
+ if (await app_client_js_1.default.isUnhealthy('connector')) {
22
+ console.error('The connector service is unhealthy, so an API token cannot be created');
23
+ return;
24
+ }
25
+ const serviceExternalID = await app_client_js_1.default.createService();
26
+ if (serviceExternalID === undefined) {
27
+ console.error('Service creation failed');
28
+ return;
29
+ }
30
+ const account = await app_client_js_1.default.createAccountInServiceWithEmailCollectionMode(serviceExternalID, 'MANDATORY');
31
+ if (account === undefined) {
32
+ console.error('Failed to create a fully set up account');
33
+ return;
34
+ }
35
+ gatewayAccountID = account.gateway_account_id;
36
+ }
37
+ else {
38
+ gatewayAccountID = args.gatewayAccountID;
39
+ }
40
+ const token = await app_client_js_1.default.createToken(gatewayAccountID);
41
+ if (token === undefined) {
42
+ console.error('Failed to create an API token');
43
+ return;
44
+ }
45
+ copyToClipboard(token);
46
+ console.log(`📋 API token “${token}” copied to clipboard`);
47
+ }
48
+ exports.default = TokenHandler;
49
+ function parseArguments(options) {
50
+ if (options.length === 0) {
51
+ return {};
52
+ }
53
+ if (options.length > 1) {
54
+ help();
55
+ throw new Error('Too many arguments');
56
+ }
57
+ return { gatewayAccountID: options[0] };
58
+ }
59
+ function copyToClipboard(token) {
60
+ const proc = (0, node_child_process_1.spawn)('pbcopy');
61
+ proc.stdin.write(token);
62
+ proc.stdin.end();
63
+ }
64
+ function help() {
65
+ console.log('Usage: pay local token [gateway_account_id]>');
66
+ }
@@ -0,0 +1,55 @@
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.ENVIRONMENT_OVERRIDES_PATH = exports.DOCKER_COMPOSE_SERVICES_CONFIG_PATH = exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const docker_compose_controller_js_1 = __importDefault(require("../docker_compose_controller.js"));
9
+ const configs_js_1 = require("../../../util/configs.js");
10
+ const pay_local_cluster_js_1 = require("../config/pay_local_cluster.js");
11
+ const renderer_js_1 = require("../config/renderer.js");
12
+ const last_up_record_js_1 = require("../config/last_up_record.js");
13
+ const default_config_setup_js_1 = require("../config/default_config_setup.js");
14
+ exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH = path_1.default.join('local', 'docker-compose', 'rendered-templates');
15
+ exports.DOCKER_COMPOSE_SERVICES_CONFIG_PATH = path_1.default.join('local', 'docker-compose', 'default-configs-DO-NOT-EDIT');
16
+ exports.ENVIRONMENT_OVERRIDES_PATH = path_1.default.join('local', 'environment-overrides');
17
+ async function UpHandler(options, onlyWriteConfig = false) {
18
+ const workspace = (0, configs_js_1.workspaceEnvVar)();
19
+ const renderedTemplatesPath = (0, configs_js_1.ensureConfigDirectory)(exports.DOCKER_COMPOSE_RENDERED_TEMPALTES_PATH);
20
+ const composeServicesConfigPath = (0, configs_js_1.ensureConfigDirectory)(exports.DOCKER_COMPOSE_SERVICES_CONFIG_PATH);
21
+ const environmentOverridesPath = (0, configs_js_1.ensureConfigDirectory)(exports.ENVIRONMENT_OVERRIDES_PATH);
22
+ (0, default_config_setup_js_1.copyDefaultConfigs)(composeServicesConfigPath);
23
+ const args = options instanceof Array ? parseArguments(options) : options;
24
+ const clusterConfig = (0, pay_local_cluster_js_1.loadClusterConfig)(args, workspace, composeServicesConfigPath, environmentOverridesPath);
25
+ const renderedTemplatePath = (0, renderer_js_1.renderDockerCompose)(clusterConfig, renderedTemplatesPath);
26
+ console.log(`docker-compose yaml written to ${renderedTemplatePath}`);
27
+ (0, last_up_record_js_1.recordUp)(renderedTemplatesPath, clusterConfig);
28
+ if (onlyWriteConfig) {
29
+ return renderedTemplatePath;
30
+ }
31
+ if (args.pull) {
32
+ console.log(`\nPulling containers for cluster ${clusterConfig.name}`);
33
+ docker_compose_controller_js_1.default.pull(renderedTemplatePath);
34
+ }
35
+ if (args.local.length > 0 && args.rebuild) {
36
+ console.log(`\nBuilding all local apps for cluster ${clusterConfig.name}`);
37
+ docker_compose_controller_js_1.default.build(renderedTemplatePath);
38
+ }
39
+ console.log(`\nGoing up with cluster ${clusterConfig.name}`);
40
+ docker_compose_controller_js_1.default.up(renderedTemplatePath);
41
+ return renderedTemplatePath;
42
+ }
43
+ exports.default = UpHandler;
44
+ function parseArguments(_options) {
45
+ return {
46
+ cluster: 'all',
47
+ apps: [],
48
+ local: [], // ['cardid', 'frontend'],
49
+ proxy: true,
50
+ with_egress_proxy: false,
51
+ rebuild: true,
52
+ pull: true,
53
+ mount_local_node_apps: false
54
+ };
55
+ }
@@ -0,0 +1,44 @@
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
+ const node_child_process_1 = require("node:child_process");
7
+ const app_client_js_1 = __importDefault(require("../app_client/app_client.js"));
8
+ const pay_local_cluster_js_1 = require("../config/pay_local_cluster.js");
9
+ async function URLHandler(options) {
10
+ const args = parseArguments(options);
11
+ const servicesConfig = (0, pay_local_cluster_js_1.loadServicesConfig)();
12
+ if (!(args.service in servicesConfig)) {
13
+ console.error(`The service specified (${args.service}) was not defined in the service_config.yaml file`);
14
+ return;
15
+ }
16
+ const serviceConfig = servicesConfig[args.service];
17
+ const url = app_client_js_1.default.externalUrlFor(args.service, '/', args.proxy);
18
+ copyToClipboard(url);
19
+ if (await app_client_js_1.default.isHealthy(serviceConfig.name)) {
20
+ console.log(`📋 “${url}” copied to clipboard`);
21
+ }
22
+ else {
23
+ console.error(`❌ “${url}” copied to clipboard, however the app did not respond successfully to ${url}/healthcheck`);
24
+ }
25
+ }
26
+ exports.default = URLHandler;
27
+ function copyToClipboard(url) {
28
+ const proc = (0, node_child_process_1.spawn)('pbcopy');
29
+ proc.stdin.write(url);
30
+ proc.stdin.end();
31
+ }
32
+ function help() {
33
+ console.log('Usage: pay local url <service>');
34
+ }
35
+ function parseArguments(options) {
36
+ if (options.length !== 1) {
37
+ help();
38
+ throw new Error('No service specified');
39
+ }
40
+ return {
41
+ service: options[0],
42
+ proxy: false
43
+ };
44
+ }