metamigo-api: runs in docker now

* great typescript module import refactor
* refactor metamigo-cli so it is the entrypoint for the db, api, and
  worker
This commit is contained in:
Abel Luck 2023-06-02 14:05:20 +00:00
parent b45e2e8c11
commit 696ba16cb7
78 changed files with 319 additions and 180 deletions

View file

@ -1,3 +1,4 @@
node_modules
out
signald
docker-compose.yml

2
.gitignore vendored
View file

@ -22,3 +22,5 @@ coverage
**/dist/**
.metamigo.local.json
out/
signald-state/*
!./signald-state/.gitkeep

View file

@ -39,6 +39,7 @@ RUN chown -R node ${APP_DIR}/
USER node
WORKDIR ${APP_DIR}
COPY --from=installer ${APP_DIR}/node_modules/ ./node_modules/
COPY --from=installer ${APP_DIR}/packages/ ./packages/
COPY --from=installer ${APP_DIR}/apps/metamigo-api/ ./apps/metamigo-api/
COPY --from=installer ${APP_DIR}/package.json ./package.json
USER root

View file

@ -1,7 +1,8 @@
{
"name": "metamigo-api",
"name": "@digiresilience/metamigo-api",
"version": "0.2.0",
"main": "build/main/cli/index.js",
"type": "module",
"main": "build/main/index.js",
"author": "Abel Luck <abel@guardianproject.info>",
"license": "AGPL-3.0-or-later",
"dependencies": {
@ -12,7 +13,6 @@
"@digiresilience/metamigo-common": "*",
"@digiresilience/metamigo-config": "*",
"@digiresilience/metamigo-db": "*",
"@digiresilience/metamigo-cli": "*",
"@digiresilience/montar": "*",
"@digiresilience/node-signald": "*",
"@graphile-contrib/pg-simplify-inflector": "^6.1.0",

View file

@ -1,9 +1,9 @@
import type * as Hapi from "@hapi/hapi";
import * as Joi from "joi";
import type { IAppConfig } from "../config";
import * as Services from "./services";
import * as Routes from "./routes";
import * as Plugins from "./plugins";
import Joi from "joi";
import type { IAppConfig } from "../config.js";
import * as Services from "./services/index.js";
import * as Routes from "./routes/index.js";
import * as Plugins from "./plugins/index.js";
const AppPlugin = {
name: "App",

View file

@ -5,10 +5,10 @@ import { makePlugin } from "@digiresilience/hapi-pg-promise";
import type { IAppConfig } from "../../config";
import { dbInitOptions, IRepositories } from "@digiresilience/metamigo-db";
import { registerNextAuth } from "./hapi-nextauth";
import { registerSwagger } from "./swagger";
import { registerNextAuthJwt } from "./nextauth-jwt";
import { registerCloudflareAccessJwt } from "./cloudflare-jwt";
import { registerNextAuth } from "./hapi-nextauth.js";
import { registerSwagger } from "./swagger.js";
import { registerNextAuthJwt } from "./nextauth-jwt.js";
import { registerCloudflareAccessJwt } from "./cloudflare-jwt.js";
import pg from "pg-promise/typescript/pg-subset";
export const register = async (

View file

@ -1,9 +1,9 @@
import isFunction from "lodash/isFunction";
import isFunction from "lodash/isFunction.js";
import type * as Hapi from "@hapi/hapi";
import * as UserRoutes from "./users";
import * as VoiceRoutes from "./voice";
import * as WhatsappRoutes from "./whatsapp";
import * as SignalRoutes from "./signal";
import * as UserRoutes from "./users/index.js";
import * as VoiceRoutes from "./voice/index.js";
import * as WhatsappRoutes from "./whatsapp/index.js";
import * as SignalRoutes from "./signal/index.js";
const loadRouteIndex = async (server, index) => {
const routes = [];

View file

@ -1,6 +1,6 @@
import * as Hapi from "@hapi/hapi";
import * as Joi from "joi";
import * as Helpers from "../helpers";
import Joi from "joi";
import * as Helpers from "../helpers/index.js";
import Boom from "@hapi/boom";
const getSignalService = (request) => request.services("app").signaldService;

View file

@ -1,11 +1,11 @@
import * as Joi from "joi";
import Joi from "joi";
import * as Hapi from "@hapi/hapi";
import {
UserRecord,
crudRoutesFor,
CrudControllerBase,
} from "@digiresilience/metamigo-common";
import * as RouteHelpers from "../helpers";
import * as RouteHelpers from "../helpers/index.js";
class UserRecordController extends CrudControllerBase(UserRecord) {}

View file

@ -1,8 +1,8 @@
import * as Hapi from "@hapi/hapi";
import * as Joi from "joi";
import Joi from "joi";
import * as Boom from "@hapi/boom";
import * as R from "remeda";
import * as Helpers from "../helpers";
import * as Helpers from "../helpers/index.js";
import Twilio from "twilio";
import {
crudRoutesFor,
@ -122,4 +122,4 @@ export const VoiceLineRoutes = Helpers.withDefaults(
)
);
export * from "./twilio";
export * from "./twilio/index.js";

View file

@ -1,13 +1,13 @@
import * as Hapi from "@hapi/hapi";
import * as Joi from "joi";
import Joi from "joi";
import * as Boom from "@hapi/boom";
import Twilio from "twilio";
import { SavedVoiceProvider } from "@digiresilience/metamigo-db";
import pMemoize from "p-memoize";
import ExpiryMap from "expiry-map";
import ms from "ms";
import * as Helpers from "../../helpers";
import workerUtils from "../../../../worker-utils";
import * as Helpers from "../../helpers/index.js";
import workerUtils from "../../../../worker-utils.js";
const queueRecording = async (meta) =>
workerUtils.addJob("twilio-recording", meta, { jobKey: meta.callSid });

View file

@ -1,5 +1,5 @@
import * as Hapi from "@hapi/hapi";
import * as Helpers from "../helpers";
import * as Helpers from "../helpers/index.js";
import Boom from "@hapi/boom";
export const GetAllWhatsappBotsRoute = Helpers.withDefaults({

View file

@ -1,7 +1,7 @@
import type * as Hapi from "@hapi/hapi";
import SettingsService from "./settings";
import WhatsappService from "./whatsapp";
import SignaldService from "./signald";
import SettingsService from "./settings.js";
import WhatsappService from "./whatsapp.js";
import SignaldService from "./signald.js";
export const register = async (server: Hapi.Server): Promise<void> => {
// register your services here

View file

@ -8,7 +8,7 @@ import {
ClientMessageWrapperv1,
} from "@digiresilience/node-signald";
import { SavedSignalBot as Bot } from "@digiresilience/metamigo-db";
import workerUtils from "../../worker-utils";
import workerUtils from "../../worker-utils.js";
export default class SignaldService extends Service {
signald: SignaldAPI;

View file

@ -15,7 +15,7 @@ import makeWASocket, {
useMultiFileAuthState,
} from "@adiwajshing/baileys";
import fs from "fs";
import workerUtils from "../../worker-utils";
import workerUtils from "../../worker-utils.js";
export type AuthCompleteCallback = (error?: string) => void;

View file

@ -0,0 +1,2 @@
export * from "./server/index.js"
export * from "./logger.js"

View file

@ -1,7 +1,7 @@
import * as Metamigo from "@digiresilience/metamigo-common";
import { defState } from "@digiresilience/montar";
import Manifest from "./manifest";
import config, { IAppConfig } from "../config";
import Manifest from "./manifest.js";
import config, { IAppConfig } from "../config.js";
export const deployment = async (
config: IAppConfig,

View file

@ -5,8 +5,8 @@ import HapiBasic from "@hapi/basic";
import HapiJwt from "hapi-auth-jwt2";
import HapiPostgraphile from "hapi-postgraphile";
import { getPostGraphileOptions } from "@digiresilience/metamigo-db";
import AppPlugin from "../app";
import type { IAppConfig } from "../config";
import AppPlugin from "../app/index.js";
import type { IAppConfig } from "../config.js";
const build = async (config: IAppConfig): Promise<Glue.Manifest> => {
const { port, address } = config.server;

View file

@ -1,6 +1,6 @@
import * as Worker from "graphile-worker";
import { defState } from "@digiresilience/montar";
import config from "./config";
import config from "./config.js";
const startWorkerUtils = async (): Promise<Worker.WorkerUtils> => {
const workerUtils = await Worker.makeWorkerUtils({

View file

@ -0,0 +1,54 @@
FROM node:20 as base
FROM base AS builder
ARG APP_DIR=/opt/metamigo-cli
RUN mkdir -p ${APP_DIR}/
RUN npm i -g turbo
WORKDIR ${APP_DIR}
COPY . .
RUN turbo prune --scope=@digiresilience/metamigo-cli --docker
FROM base AS installer
ARG APP_DIR=/opt/metamigo-cli
WORKDIR ${APP_DIR}
COPY .gitignore .gitignore
COPY --from=builder ${APP_DIR}/out/json/ .
COPY --from=builder ${APP_DIR}/out/package-lock.json ./package-lock.json
RUN npm ci --omit=dev
COPY --from=builder ${APP_DIR}/out/full/ .
RUN npm i -g turbo
RUN turbo run build --filter=metamigo-cli
FROM base AS runner
ARG APP_DIR=/opt/metamigo-cli
WORKDIR ${APP_DIR}/
ARG BUILD_DATE
ARG VERSION
LABEL maintainer="Darren Clarke <darren@redaranj.com>"
LABEL org.label-schema.build-date=$BUILD_DATE
LABEL org.label-schema.version=$VERSION
ENV APP_DIR ${APP_DIR}
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
apt-get install -y --no-install-recommends \
dumb-init
RUN mkdir -p ${APP_DIR}
RUN chown -R node ${APP_DIR}/
USER node
WORKDIR ${APP_DIR}
COPY --from=installer ${APP_DIR}/node_modules/ ./node_modules/
COPY --from=installer ${APP_DIR}/packages/ ./packages/
COPY --from=installer ${APP_DIR}/apps/metamigo-cli/ ./apps/metamigo-cli/
COPY --from=installer ${APP_DIR}/apps/metamigo-api/ ./apps/metamigo-api/
COPY --from=installer ${APP_DIR}/apps/metamigo-worker/ ./apps/metamigo-worker/
COPY --from=installer ${APP_DIR}/package.json ./package.json
USER root
WORKDIR ${APP_DIR}/apps/metamigo-cli/
RUN chmod +x docker-entrypoint.sh
USER node
EXPOSE 3000
ENV PORT 3000
ENV NODE_ENV production
ENTRYPOINT ["/opt/metamigo-cli/apps/metamigo-cli/docker-entrypoint.sh"]

4
apps/metamigo-cli/cli Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
node ./build/main/index.js ${@}

View file

@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -e
if [[ "$1" == "api" ]]; then
echo "docker-entrypoint: starting api server"
./cli db -- migrate
exec dumb-init ./cli api
elif [[ "$1" == "worker" ]]; then
echo "docker-entrypoint: starting worker"
exec dumb-init ./cli worker
elif [[ "$1" == "frontend" ]]; then
echo "docker-entrypoint: starting frontend"
exec dumb-init yarn workspace @app/frontend start
elif [[ "$1" == "cli" ]]; then
echo "docker-entrypoint: starting frontend"
shift 1
exec ./cli "$@"
else
echo "docker-entrypoint: missing argument, one of: api, worker, frontend, cli"
exit 1
fi

View file

@ -4,10 +4,16 @@
"main": "build/main/index.js",
"author": "Abel Luck <abel@guardianproject.info>",
"license": "AGPL-3.0-or-later",
"type": "module",
"bin": {
"metamigo": "./build/main/index.js"
},
"dependencies": {
"@digiresilience/montar": "*",
"@digiresilience/metamigo-config": "*",
"@digiresilience/metamigo-db": "*",
"@digiresilience/metamigo-api": "*",
"@digiresilience/metamigo-worker": "*",
"commander": "^10.0.1",
"graphile-migrate": "^1.4.1",
"graphile-worker": "^0.13.0",
@ -16,6 +22,7 @@
"graphql": "16.6.0"
},
"devDependencies": {
"@types/jest": "^29.5.1",
"pino-pretty": "^10.0.0",
"nodemon": "^2.0.22",
"tsconfig-link": "*",

View file

@ -4,12 +4,11 @@ import { Command } from "commander";
import { startWithout } from "@digiresilience/montar";
import { migrateWrapper } from "@digiresilience/metamigo-db";
import { loadConfig } from "@digiresilience/metamigo-config";
import { genConf, listConfig } from "./config";
import { createTokenForTesting, generateJwks } from "./jwks";
import { exportGraphqlSchema } from "./metamigo-postgraphile";
import "api/build/main/server";
import "api/build/main/logger";
import "worker/build/main";
import { genConf, listConfig } from "./config.js";
import { createTokenForTesting, generateJwks } from "./jwks.js";
import { exportGraphqlSchema } from "./metamigo-postgraphile.js";
import "@digiresilience/metamigo-api";
import "@digiresilience/metamigo-worker";
const program = new Command();

View file

@ -7,10 +7,12 @@ import {
printSchema,
} from "graphql";
import { createPostGraphileSchema } from "postgraphile";
import { Pool } from "pg";
import pg from "pg";
import { loadConfig } from "@digiresilience/metamigo-config";
import { getPostGraphileOptions } from "@digiresilience/metamigo-db";
const {Pool} = pg;
export const exportGraphqlSchema = async (): Promise<void> => {
const config = await loadConfig();

View file

@ -2,10 +2,10 @@ import * as Worker from "graphile-worker";
import { parseCronItems } from "graphile-worker";
import { defState } from "@digiresilience/montar";
import config from "@digiresilience/metamigo-config";
import { initPgp } from "./db";
import logger from "./logger";
import workerUtils from "./utils";
import { assertFfmpegAvailable } from "./lib/media-convert";
import { initPgp } from "./db.js";
import logger from "./logger.js";
import workerUtils from "./utils.js";
import { assertFfmpegAvailable } from "./lib/media-convert.js";
const logFactory = (scope: any) => (level: any, message: any, meta: any) => {
const pinoLevel = level === "warning" ? "warn" : level;

View file

@ -1,7 +1,8 @@
{
"name": "metamigo-worker",
"name": "@digiresilience/metamigo-worker",
"version": "0.2.0",
"main": "build/main/index.js",
"type": "module",
"author": "Abel Luck <abel@guardianproject.info>",
"license": "AGPL-3.0-or-later",
"dependencies": {

View file

@ -181,7 +181,7 @@ services:
metamigo-api:
build:
context: .
dockerfile: ./apps/metamigo-api/Dockerfile
dockerfile: ./apps/metamigo-cli/Dockerfile
container_name: metamigo-api
restart: ${RESTART}
command: [ "api" ]
@ -189,7 +189,7 @@ services:
- 127.0.0.1:8004:3001
environment: *common-metamigo-variables
volumes:
- ./signald:/signald
- ./signald-state:/signald
depends_on:
- metamigo-postgresql
- signald
@ -221,7 +221,7 @@ services:
restart: ${RESTART}
user: ${CURRENT_UID}
volumes:
- ../signald:/signald
- ./signald-state:/signald
environment:
<<: *common-global-variables

55
package-lock.json generated
View file

@ -112,6 +112,7 @@
}
},
"apps/metamigo-api": {
"name": "@digiresilience/metamigo-api",
"version": "0.2.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
@ -119,7 +120,6 @@
"@adiwajshing/keyed-db": "0.2.4",
"@digiresilience/hapi-nextauth": "*",
"@digiresilience/hapi-pg-promise": "*",
"@digiresilience/metamigo-cli": "*",
"@digiresilience/metamigo-common": "*",
"@digiresilience/metamigo-config": "*",
"@digiresilience/metamigo-db": "*",
@ -443,6 +443,35 @@
"node": ">=0.4"
}
},
"apps/metamigo-cli": {
"version": "0.2.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@digiresilience/metamigo-api": "*",
"@digiresilience/metamigo-config": "*",
"@digiresilience/metamigo-db": "*",
"@digiresilience/montar": "*",
"commander": "^10.0.1",
"graphile-migrate": "^1.4.1",
"graphile-worker": "^0.13.0",
"graphql": "16.6.0",
"node-jose": "^2.2.0",
"postgraphile": "4.13.0"
},
"bin": {
"metamigo": "build/main/index.js"
},
"devDependencies": {
"@types/jest": "^29.5.1",
"babel-preset-link": "*",
"eslint-config-link": "*",
"jest-config-link": "*",
"nodemon": "^2.0.22",
"pino-pretty": "^10.0.0",
"tsconfig-link": "*",
"typescript": "^5.0.4"
}
},
"apps/metamigo-frontend": {
"version": "0.2.0",
"dependencies": {
@ -487,6 +516,7 @@
}
},
"apps/metamigo-worker": {
"name": "@digiresilience/metamigo-worker",
"version": "0.2.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
@ -2258,8 +2288,12 @@
"resolved": "packages/hapi-pg-promise",
"link": true
},
"node_modules/@digiresilience/metamigo-api": {
"resolved": "apps/metamigo-api",
"link": true
},
"node_modules/@digiresilience/metamigo-cli": {
"resolved": "packages/metamigo-cli",
"resolved": "apps/metamigo-cli",
"link": true
},
"node_modules/@digiresilience/metamigo-common": {
@ -2274,6 +2308,10 @@
"resolved": "packages/metamigo-db",
"link": true
},
"node_modules/@digiresilience/metamigo-worker": {
"resolved": "apps/metamigo-worker",
"link": true
},
"node_modules/@digiresilience/montar": {
"resolved": "packages/montar",
"link": true
@ -14986,18 +15024,10 @@
"node": ">= 8"
}
},
"node_modules/metamigo-api": {
"resolved": "apps/metamigo-api",
"link": true
},
"node_modules/metamigo-frontend": {
"resolved": "apps/metamigo-frontend",
"link": true
},
"node_modules/metamigo-worker": {
"resolved": "apps/metamigo-worker",
"link": true
},
"node_modules/micromark": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/micromark/-/micromark-3.1.0.tgz",
@ -21882,6 +21912,7 @@
"packages/metamigo-cli": {
"name": "@digiresilience/metamigo-cli",
"version": "0.2.0",
"extraneous": true,
"license": "AGPL-3.0-or-later",
"dependencies": {
"@digiresilience/metamigo-config": "*",
@ -21894,7 +21925,11 @@
"node-jose": "^2.2.0",
"postgraphile": "4.13.0"
},
"bin": {
"metamigo": "build/main/index.js"
},
"devDependencies": {
"@types/jest": "^29.5.1",
"babel-preset-link": "*",
"eslint-config-link": "*",
"jest-config-link": "*",

View file

@ -6,7 +6,7 @@ This is a plugin for hapi.js that exposes [NextAuth's database adapter](https://
```typescript
import * as Hapi from "@hapi/hapi";
import * as Joi from "joi";
import Joi from "joi";
import NextAuthPlugin from "@digiresilience/hapi-nextauth";
import type { AdapterInstance } from "next-auth/adapters";

View file

@ -3,6 +3,7 @@
"version": "1.0.0",
"description": "a plugin for hapi.js that exposes NextAuth's database adapter via HTTP",
"main": "build/main/index.js",
"type": "module",
"author": "Abel Luck <abel@guardianproject.info>",
"license": "AGPL-3.0-or-later",
"private": false,

View file

@ -1,9 +1,9 @@
import * as Hapi from "@hapi/hapi";
import * as Hoek from "@hapi/hoek";
import * as Joi from "joi";
import Joi from "joi";
import { NextAuthPluginOptions } from "./types";
import * as Routes from "./routes";
import { NextAuthPluginOptions } from "./types.js";
import * as Routes from "./routes.js";
const minimumProfileSchema = Joi.object()
.keys({
@ -98,5 +98,5 @@ const nextAuthPlugin = {
version: "0.0.3",
};
export * from "./types";
export * from "./types.js";
export default nextAuthPlugin;

View file

@ -1,5 +1,5 @@
/* eslint-disable unicorn/no-null */
import * as Joi from "joi";
import Joi from "joi";
import * as Hapi from "@hapi/hapi";
import { ResponseToolkit, ResponseObject } from "@hapi/hapi";

View file

@ -3,6 +3,7 @@
"version": "1.0.0",
"description": "a hapi.js plugin for pg-promise",
"main": "build/main/index.js",
"type": "module",
"author": "Abel Luck <abel@guardianproject.info>",
"license": "AGPL-3.0-or-later",
"private": false,

View file

@ -1,12 +1,12 @@
import * as Hapi from "@hapi/hapi";
import pgPromise from "pg-promise";
import * as pgMonitor from "pg-monitor";
import pgMonitor from "pg-monitor";
import type { IConnectionParameters } from "pg-promise/typescript/pg-subset";
import type { IMain, IInitOptions } from "pg-promise";
import { IPGPPluginOptions, ExtendedProtocol } from "./types";
import { IPGPPluginOptions, ExtendedProtocol } from "./types.js";
import { Plugin } from "@hapi/hapi/lib/types/plugin";
export * from "./types";
export * from "./types.js";
export const startDiagnostics = <T>(
logSql: boolean,

View file

@ -3,6 +3,7 @@
"version": "0.2.0",
"description": "",
"main": "build/main/index.js",
"type": "module",
"types": "build/main/index.d.ts",
"author": "Abel Luck <abel@guardianproject.info>",
"license": "AGPL-3.0-or-later",

View file

@ -1,4 +1,4 @@
import { ConvictSchema } from "./types";
import { ConvictSchema } from "./types.js";
export interface IAppMetaConfig {
name: string;

View file

@ -1,4 +1,4 @@
import { ConvictSchema } from "./types";
import { ConvictSchema } from "./types.js";
export interface ISessionConfig {
sessionMaxAgeSeconds: number;

View file

@ -1,4 +1,4 @@
import { ConvictSchema } from "./types";
import { ConvictSchema } from "./types.js";
export interface ICorsConfig {
allowedMethods: Array<string>;

View file

@ -1,4 +1,4 @@
import * as Joi from "joi";
import Joi from "joi";
import type { Format } from "convict";
// eslint-disable-next-line @typescript-eslint/no-explicit-any

View file

@ -1,12 +1,12 @@
import process from "node:process";
import convict, { SchemaObj } from "convict";
import { IServerConfig, ServerConfig } from "./server";
import { IMetricsConfig, MetricsConfig } from "./metrics-server";
import { IAppMetaConfig, AppMetaConfig } from "./app-meta";
import { ICorsConfig, CorsConfig } from "./cors";
import { ILoggingConfig, LoggingConfig } from "./logging";
import { ExtendedConvict } from "./types";
import { MetamigoConvictFormats } from "./formats";
import { IServerConfig, ServerConfig } from "./server.js";
import { IMetricsConfig, MetricsConfig } from "./metrics-server.js";
import { IAppMetaConfig, AppMetaConfig } from "./app-meta.js";
import { ICorsConfig, CorsConfig } from "./cors.js";
import { ILoggingConfig, LoggingConfig } from "./logging.js";
import { ExtendedConvict } from "./types.js";
import { MetamigoConvictFormats } from "./formats.js";
type IEnvConfig = "production" | "development" | "test";
@ -51,10 +51,10 @@ export type IMetamigoConvict = ExtendedConvict<IMetamigoConfig>;
export type { IMetamigoConfig };
export * from "./formats";
export * from "./generate";
export * from "./print";
export * from "./types";
export * from "./formats.js";
export * from "./generate.js";
export * from "./print.js";
export * from "./types.js";
/**
* Loads your applications configuration from environment variables and configuration files (see METAMIGO_CONFIG).
@ -137,8 +137,8 @@ export const loadConfiguration = async <T extends IMetamigoConfig>(
return c.getProperties();
};
export { type IServerConfig } from "./server";
export { type IMetricsConfig } from "./metrics-server";
export { type IAppMetaConfig } from "./app-meta";
export { type ICorsConfig } from "./cors";
export { type ILoggingConfig } from "./logging";
export { type IServerConfig } from "./server.js";
export { type IMetricsConfig } from "./metrics-server.js";
export { type IAppMetaConfig } from "./app-meta.js";
export { type ICorsConfig } from "./cors.js";
export { type ILoggingConfig } from "./logging.js";

View file

@ -1,4 +1,4 @@
import { ConvictSchema } from "./types";
import { ConvictSchema } from "./types.js";
export interface ILoggingConfig {
level: string;

View file

@ -1,4 +1,4 @@
import { ConvictSchema } from "./types";
import { ConvictSchema } from "./types.js";
export interface IMetricsConfig {
address: string;

View file

@ -1,4 +1,4 @@
import { ConvictSchema } from "./types";
import { ConvictSchema } from "./types.js";
export interface IServerConfig {
address: string;

View file

@ -1,14 +1,14 @@
/* eslint-disable @typescript-eslint/no-explicit-any,max-params */
import * as Boom from "@hapi/boom";
import * as Hapi from "@hapi/hapi";
import { CrudRepository } from "../records/crud-repository";
import { createResponse } from "../helpers/response";
import { CrudRepository } from "../records/crud-repository.js";
import { createResponse } from "../helpers/response.js";
import {
PgRecordInfo,
UnsavedR,
SavedR,
KeyType,
} from "../records/record-info";
} from "../records/record-info.js";
/**
*

View file

@ -1,10 +1,10 @@
/* eslint-disable unicorn/no-null,max-params */
import { createHash, randomBytes } from "node:crypto";
import omit from "lodash/omit";
import type { IMetamigoRepositories } from "../records";
import type { UnsavedAccount } from "../records/account";
import type { UserId, UnsavedUser, SavedUser } from "../records/user";
import type { UnsavedSession, SavedSession } from "../records/session";
import omit from "lodash/omit.js";
import type { IMetamigoRepositories } from "../records/index.js";
import type { UnsavedAccount } from "../records/account.js";
import type { UserId, UnsavedUser, SavedUser } from "../records/user.js";
import type { UnsavedSession, SavedSession } from "../records/session.js";
// Sessions expire after 30 days of being idle
export const defaultSessionMaxAge = 30 * 24 * 60 * 60 * 1000;

View file

@ -8,11 +8,11 @@ import PinoPlugin from "hapi-pino";
import { createServer as createPrometheusServer } from "@promster/server";
import { createHttpTerminator } from "http-terminator";
import { getPrettyPrint } from "./logger";
import RequestIdPlugin from "./plugins/request-id";
import StatusPlugin from "./plugins/status";
import ConfigPlugin from "./plugins/config";
import { IMetamigoConfig } from "./config";
import { getPrettyPrint } from "./logger.js";
import RequestIdPlugin from "./plugins/request-id.js";
import StatusPlugin from "./plugins/status.js";
import ConfigPlugin from "./plugins/config.js";
import { IMetamigoConfig } from "./config/index.js";
export interface Server {
hapiServer: Hapi.Server;

View file

@ -1,7 +1,7 @@
import process from "node:process";
import * as Hapi from "@hapi/hapi";
import * as Joi from "joi";
import Hoek from "@hapi/hoek";
import Joi from "joi";
import * as Hoek from "@hapi/hoek";
import * as Boom from "@hapi/boom";
export interface HapiValidationError extends Joi.ValidationError {

View file

@ -1,12 +1,12 @@
export * from "./config";
export * from "./controllers/crud-controller";
export * from "./controllers/nextauth-adapter";
export * from "./hapi";
export * from "./helpers";
export * from "./helpers/response";
export * from "./helpers/validation-error";
export * from "./logger";
export * from "./records";
export * from "./config/index.js";
export * from "./controllers/crud-controller.js";
export * from "./controllers/nextauth-adapter.js";
export * from "./hapi.js";
export * from "./helpers/index.js";
export * from "./helpers/response.js";
export * from "./helpers/validation-error.js";
export * from "./logger.js";
export * from "./records/index.js";
import * as pino from "pino";

View file

@ -1,5 +1,5 @@
import pino, { LoggerOptions } from "pino";
import { IMetamigoConfig } from "./config";
import { IMetamigoConfig } from "./config/index.js";
export const getPrettyPrint = <T extends IMetamigoConfig>(
config: T

View file

@ -1,6 +1,6 @@
import { Server } from "@hapi/hapi";
import cloneDeep from "lodash/cloneDeep";
import { deepFreeze } from "../helpers";
import cloneDeep from "lodash/cloneDeep.js";
import { deepFreeze } from "../helpers/index.js";
interface ConfigOptions {
config: unknown;

View file

@ -1,7 +1,7 @@
import { recordInfo } from "./record-info";
import { RepositoryBase } from "./base";
import { recordInfo } from "./record-info.js";
import { RepositoryBase } from "./base.js";
import { Flavor, UUID } from "../helpers";
import { UserId } from "./user";
import { UserId } from "./user.js";
export type AccountId = Flavor<UUID, "Account Id">;

View file

@ -1,7 +1,7 @@
import { TableName } from "pg-promise";
import { IMain } from "../db/types";
import { CrudRepository } from "./crud-repository";
import { PgRecordInfo, UnsavedR, SavedR, KeyType } from "./record-info";
import { IMain } from "../db/types.js";
import { CrudRepository } from "./crud-repository.js";
import { PgRecordInfo, UnsavedR, SavedR, KeyType } from "./record-info.js";
import type { IDatabase } from "pg-promise";
export type PgProtocol<T> = IDatabase<T> & T;

View file

@ -1,13 +1,13 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { TableName } from "pg-promise";
import decamelcaseKeys from "decamelcase-keys";
import isObject from "lodash/isObject";
import isArray from "lodash/isArray";
import zipObject from "lodash/zipObject";
import isEmpty from "lodash/isEmpty";
import omit from "lodash/omit";
import { IDatabase, IMain, IResult } from "../db/types";
import { PgRecordInfo, idKeysOf } from "./record-info";
import isObject from "lodash/isObject.js";
import isArray from "lodash/isArray.js";
import zipObject from "lodash/zipObject.js";
import isEmpty from "lodash/isEmpty.js";
import omit from "lodash/omit.js";
import { IDatabase, IMain, IResult } from "../db/types.js";
import { PgRecordInfo, idKeysOf } from "./record-info.js";
export interface ICrudRepository<
TUnsavedR,

View file

@ -1,13 +1,13 @@
export * from "./base";
export * from "./record-info";
export * from "./crud-repository";
export * from "./user";
export * from "./session";
export * from "./account";
export * from "./base.js";
export * from "./record-info.js";
export * from "./crud-repository.js";
export * from "./user.js";
export * from "./session.js";
export * from "./account.js";
import type { AccountRecordRepository } from "./account";
import type { UserRecordRepository } from "./user";
import type { SessionRecordRepository } from "./session";
import type { AccountRecordRepository } from "./account.js";
import type { UserRecordRepository } from "./user.js";
import type { SessionRecordRepository } from "./session.js";
export interface IMetamigoRepositories {
users: UserRecordRepository;

View file

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import at from "lodash/at";
import pick from "lodash/pick";
import at from "lodash/at.js";
import pick from "lodash/pick.js";
export interface EntityType<
TUnsaved = any,

View file

@ -1,7 +1,7 @@
import { recordInfo } from "./record-info";
import { RepositoryBase } from "./base";
import { recordInfo } from "./record-info.js";
import { RepositoryBase } from "./base.js";
import { Flavor, UUID } from "../helpers";
import { UserId } from "./user";
import { UserId } from "./user.js";
export type SessionId = Flavor<UUID, "Session Id">;

View file

@ -1,5 +1,5 @@
import { recordInfo } from "./record-info";
import { RepositoryBase } from "./base";
import { recordInfo } from "./record-info.js";
import { RepositoryBase } from "./base.js";
import { Flavor, UUID } from "../helpers";
export type UserId = Flavor<UUID, "User Id">;

View file

@ -2,6 +2,7 @@
"name": "@digiresilience/metamigo-config",
"version": "0.2.0",
"main": "build/main/index.js",
"type": "module",
"author": "Abel Luck <abel@guardianproject.info>",
"license": "AGPL-3.0-or-later",
"dependencies": {

View file

@ -3,6 +3,7 @@
"private": true,
"version": "0.2.0",
"main": "build/main/index.js",
"type": "module",
"author": "Abel Luck <abel@guardianproject.info>",
"license": "AGPL-3.0-or-later",
"dependencies": {

View file

@ -1,6 +1,8 @@
import process from "node:process";
import { existsSync } from "node:fs";
import path from "node:path";
import { exec } from "node:child_process";
import { fileURLToPath } from 'node:url';
import type { IAppConfig } from "@digiresilience/metamigo-config";
/**
@ -34,10 +36,11 @@ export const migrateWrapper = async (
DATABASE_VISITOR: config.postgraphile.visitor,
};
const cmd = `npx --no-install graphile-migrate ${commands.join(" ")}`;
const dbDir = `../../db`;
const gmrc = `${dbDir}/.gmrc`;
if (!existsSync(gmrc)) {
throw new Error(`graphile migrate config not found at ${gmrc}`);
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const dbDir = path.resolve(__dirname, '../../');
const gmrcPath = path.resolve(__dirname, '../../.gmrc');
if (!existsSync(gmrcPath)) {
throw new Error(`graphile migrate config not found at ${gmrcPath}`);
}
if (!silent) console.log("executing:", cmd);

View file

@ -2,7 +2,7 @@ import type { IAppConfig } from "@digiresilience/metamigo-config";
import camelcaseKeys from "camelcase-keys";
import PgSimplifyInflectorPlugin from "@graphile-contrib/pg-simplify-inflector";
import PgManyToManyPlugin from "@graphile-contrib/pg-many-to-many";
import * as ConnectionFilterPlugin from "postgraphile-plugin-connection-filter";
import ConnectionFilterPlugin from "postgraphile-plugin-connection-filter";
import type { PostGraphileOptions } from "postgraphile";
import {
@ -20,7 +20,7 @@ import {
WhatsappMessageRecordRepository,
WhatsappAttachmentRecordRepository,
SignalBotRecordRepository,
} from "./records";
} from "./records/index.js";
import type { IInitOptions, IDatabase } from "pg-promise";
@ -83,5 +83,5 @@ export const getPostGraphileOptions = (): PostGraphileOptions => ({
],
});
export * from "./helpers";
export * from "./records";
export * from "./helpers.js";
export * from "./records/index.js";

View file

@ -1,9 +1,9 @@
export * from "./settings";
export * from "./signal/bots";
export * from "./whatsapp/bots";
export * from "./whatsapp/messages";
export * from "./whatsapp/attachments";
export * from "./settings";
export * from "./voice/voice-line";
export * from "./voice/voice-provider";
export * from "./webhooks";
export * from "./settings.js";
export * from "./signal/bots.js";
export * from "./whatsapp/bots.js";
export * from "./whatsapp/messages.js";
export * from "./whatsapp/attachments.js";
export * from "./settings.js";
export * from "./voice/voice-line.js";
export * from "./voice/voice-provider.js";
export * from "./webhooks.js";

View file

@ -3,6 +3,7 @@
"version": "0.1.7",
"description": "manage typescript state",
"main": "build/main/index.js",
"type": "module",
"typings": "build/main/index.d.ts",
"module": "build/module/index.js",
"author": "Abel Luck <abel@guardianproject.info>",

View file

@ -4,7 +4,7 @@
/* eslint-disable no-await-in-loop */
import Debug from "debug";
import { mutableProxyFactory } from "./proxy";
import { mutableProxyFactory } from "./proxy.js";
const debug = Debug("montar");

View file

@ -5,6 +5,7 @@
"author": "Abel Luck <abel@guardianproject.info>",
"license": "AGPL-3.0-only",
"private": false,
"type": "module",
"main": "build/main/index.js",
"types": "types/main/index.d.ts",
"files": [

View file

@ -1,4 +1,4 @@
import { SignaldGeneratedApi, JsonMessageEnvelopev1 } from "./generated";
import { SignaldGeneratedApi, JsonMessageEnvelopev1 } from "./generated.js";
export class SignaldAPI extends SignaldGeneratedApi {
constructor() {

View file

@ -2,7 +2,7 @@
Date: Mon Jan 03 2022 09:59:39 GMT+0000 (Coordinated Universal Time)
Version: 0.15.0-40-56a6c9d2
*/
import { JSONTransport } from "./util";
import { JSONTransport } from "./util.js";
export type JsonAccountListv0 = {
accounts?: JsonAccountv0[];

View file

@ -1,5 +1,5 @@
export { SignaldAPI } from "./api";
export { JSONTransport, EventTypes } from "./util";
export { SignaldError, CaptchaRequiredException } from "./error";
import "./util";
export * from "./generated";
export { SignaldAPI } from "./api.js";
export { JSONTransport, EventTypes } from "./util.js";
export { SignaldError, CaptchaRequiredException } from "./error.js";
import "./util.js";
export * from "./generated.js";

View file

@ -2,7 +2,7 @@ import EventEmitter from "eventemitter3";
import { v4 as uuid } from "uuid";
import * as backoff from "backoff";
import * as net from "net";
import { throwOnError } from "./error";
import { throwOnError } from "./error.js";
export interface EventTypes {
/**

View file

@ -3,8 +3,8 @@
"incremental": true,
"target": "es2020",
"lib": ["es2020"],
"module": "ES2020",
"moduleResolution": "node",
"module": "commonjs",
"declaration": true,
"inlineSourceMap": true,
"esModuleInterop": true,

0
signald-state/.gitkeep Normal file
View file