Skip to content

Commit

Permalink
bin/repl: run NodeJS REPL with initialised container (#1191)
Browse files Browse the repository at this point in the history
Example use:

    ./lib/bin/repl
    Available vars: Actees, Actors, Analytics, Assignments, Audits, Auth, Blobs, ClientAudits, Comments, Configs, Datasets, Entities, FieldKeys, FormAttachments, Forms, Keys, Projects, PublicLinks, Roles, Sentry, Sessions, SubmissionAttachments, Submissions, Users, all, db, enketo, env, mail, maybeOne, maybeOneFirst, one, oneFirst, run, s3, sql, stream, with, xlsform
    > await db.any(sql`SELECT * FROM blobs`)
    []
  • Loading branch information
alxndrsn authored Oct 2, 2024
1 parent 66ecf31 commit 82696a0
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 30 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ node_modules/
.idea/
/.eslintcache
/.pgbadger/
/.repl-history
.vscode
/junit-reports/
41 changes: 41 additions & 0 deletions lib/bin/repl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2024 ODK Central Developers
// See the NOTICE file at the top-level directory of this distribution and at
// https://github.com/getodk/central-backend/blob/master/NOTICE.
// This file is part of ODK Central. It is subject to the license terms in
// the LICENSE file found in the top-level directory of this distribution and at
// https://www.apache.org/licenses/LICENSE-2.0. No part of ODK Central,
// including this file, may be copied, modified, propagated, or distributed
// except according to the terms contained in the LICENSE file.

const should = require('should'); // eslint-disable-line import/no-extraneous-dependencies
require('../../test/assertions');

const _ = require('lodash'); // eslint-disable-line import/no-extraneous-dependencies
const { sql } = require('slonik');

const container = require('../util/default-container');

(async () => {
const context = { ..._.omit(container, 'with'), container, should, sql };
const contextKeys = Object.keys(context).sort();
console.log('Available vars:', contextKeys.join(', '));

const repl = require('repl').start({
useGlobal: true, // enable should.js prototype pollution
});

await new Promise((resolve, reject) => {
repl.setupHistory('.repl-history', err => {
if (err) reject(err);
else resolve();
});
});

Object.entries(context).forEach(([k, value]) => {
Object.defineProperty(repl.context, k, {
configurable: false,
enumerable: true,
value,
});
});
})();
32 changes: 2 additions & 30 deletions lib/bin/run-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,44 +10,16 @@
// This is the main entrypoint for the actual HTTP server. It sets up the
// dependency container and feeds it to the service infrastructure.

const { mergeRight } = require('ramda');
const config = require('config');
const exit = require('express-graceful-exit');

global.tap = (x) => { console.log(x); return x; }; // eslint-disable-line no-console

////////////////////////////////////////////////////////////////////////////////
// CONTAINER SETUP

// initialize our slonik connection pool.
const { slonikPool } = require('../external/slonik');
const db = slonikPool(config.get('default.database'));

// set up our mailer.
const env = config.get('default.env');
const { mailer } = require('../external/mail');
const mail = mailer(mergeRight(config.get('default.email'), { env }));

// get a sentry and configure errors.
const Sentry = require('../external/sentry').init(config.get('default.external.sentry'));
Error.stackTrackLimit = 20;

// get an xlsform client and a password module.
const xlsform = require('../external/xlsform').init(config.get('default.xlsform'));

// get an Enketo client
const enketo = require('../external/enketo').init(config.get('default.enketo'));

// get an S3 client.
const s3 = require('../external/s3').init(config.get('default.external.s3blobStore'));


////////////////////////////////////////////////////////////////////////////////
// START HTTP SERVICE

// initialize our container, then generate an http service out of it.
const container = require('../model/container')
.withDefaults({ db, mail, env, Sentry, xlsform, enketo, s3 });
const container = require('../util/default-container');
const service = require('../http/service')(container);

// insert the graceful exit middleware.
Expand Down Expand Up @@ -81,7 +53,7 @@ const term = () => {
exit.gracefulExitHandler(service, server, {
log: true,
exitProcess: false,
callback: () => db.end().then(() => process.exit(0))
callback: () => container.db.end().then(() => process.exit(0))
});
};

Expand Down
41 changes: 41 additions & 0 deletions lib/util/default-container.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2024 ODK Central Developers
// See the NOTICE file at the top-level directory of this distribution and at
// https://github.com/getodk/central-backend/blob/master/NOTICE.
// This file is part of ODK Central. It is subject to the license terms in
// the LICENSE file found in the top-level directory of this distribution and at
// https://www.apache.org/licenses/LICENSE-2.0. No part of ODK Central,
// including this file, may be copied, modified, propagated, or distributed
// except according to the terms contained in the LICENSE file.

const { mergeRight } = require('ramda');
const config = require('config');

////////////////////////////////////////////////////////////////////////////////
// CONTAINER SETUP

// initialize our slonik connection pool.
const { slonikPool } = require('../external/slonik');
const db = slonikPool(config.get('default.database'));

// set up our mailer.
const env = config.get('default.env');
const { mailer } = require('../external/mail');
const mail = mailer(mergeRight(config.get('default.email'), { env }));

// get a sentry and configure errors.
const Sentry = require('../external/sentry').init(config.get('default.external.sentry'));
Error.stackTrackLimit = 20;

// get an xlsform client and a password module.
const xlsform = require('../external/xlsform').init(config.get('default.xlsform'));

// get an Enketo client
const enketo = require('../external/enketo').init(config.get('default.enketo'));

// get an S3 client.
const s3 = require('../external/s3').init(config.get('default.external.s3blobStore'));

const container = require('../model/container')
.withDefaults({ db, mail, env, Sentry, xlsform, enketo, s3 });

module.exports = container;

0 comments on commit 82696a0

Please sign in to comment.