gristlabs_grist-core/package.json
Paul Fitzpatrick e6983e9209 (core) add machinery for self-managed flavor of Grist
Summary:
Currently, we have two ways that we deliver Grist. One is grist-core,
which has simple defaults and is relatively easy for third parties to
deploy. The second is our internal build for our SaaS, which is the
opposite. For self-managed Grist, a planned paid on-premise version
of Grist, I adopt the following approach:

 * Use the `grist-core` build mechanism, extending it to accept an
   overlay of extra code if present.
 * Extra code is supplied in a self-contained `ext` directory, with
   an `ext/app` directory that is of same structure as core `app`
   and `stubs/app`.
 * The `ext` directory also contains information about extra
   node dependencies needed beyond that of `grist-core`.
 * The `ext` directory is contained within our monorepo rather than
   `grist-core` since it may contain material not under the Apache
   license.

Docker builds are achieved in our monorepo by using the `--build-context`
functionality to add in `ext` during the regular `grist-core` build:

```
docker buildx build --load -t gristlabs/grist-ee --build-context=ext=../ext .
```

Incremental builds in our monorepo are achieved with the `build_core.sh` helper,
like:

```
buildtools/build_core.sh /tmp/self-managed
cd /tmp/self-managed
yarn start
```

The initial `ext` directory contains material for snapshotting to S3.
If you build the docker image as above, and have S3 access, you can
do something like:

```
docker run -p 8484:8484 --env GRIST_SESSION_SECRET=a-secret \
  --env GRIST_DOCS_S3_BUCKET=grist-docs-test \
  --env GRIST_DOCS_S3_PREFIX=self-managed \
  -v $HOME/.aws:/root/.aws -it gristlabs/grist-ee
```

This will start a version of Grist that is like `grist-core` but with
S3 snapshots enabled. To release this code to `grist-core`, it would
just need to move from `ext/app` to `app` within core.

I tried a lot of ways of organizing self-managed Grist, and this was
what made me happiest. There are a lot of trade-offs, but here is what
I was looking for:

 * Only OSS-code in grist-core. Adding mixed-license material there
   feels unfair to people already working with the repo. That said,
   a possible future is to move away from our private monorepo to
   a public mixed-licence repo, which could have the same relationship
   with grist-core as the monorepo has.
 * Minimal differences between self-managed builds and one of our
   existing builds, ideally hewing as close to grist-core as possible
   for ease of documentation, debugging, and maintenance.
 * Ideally, docker builds without copying files around (the new
   `--build-context` functionality made that possible).
 * Compatibility with monorepo build.

Expressing dependencies of the extra code in `ext` proved tricky to
do in a clean way. Yarn/npm fought me every step of the way - everything
related to optional dependencies was unsatisfactory in some respect.
Yarn2 is flexible but smells like it might be overreach. In the end,
organizing to install non-core dependencies one directory up from the
main build was a good simple trick that saved my bacon.

This diff gets us to the point of building `grist-ee` images conveniently,
but there isn't a public repo people can go look at to see its source. This
could be generated by taking `grist-core`, adding the `ext` directory
to it, and pushing to a distinct repository. I'm not in a hurry to do that,
since a PR to that repo would be hard to sync with our monorepo and
`grist-core`. Also, we don't have any licensing text ready for the `ext`
directory. So leaving that for future work.

Test Plan: manual

Reviewers: georgegevoian, alexmojaki

Reviewed By: georgegevoian, alexmojaki

Differential Revision: https://phab.getgrist.com/D3415
2022-05-12 12:39:52 -04:00

146 lines
4.6 KiB
JSON

{
"name": "grist-core",
"version": "0.7.8",
"license": "Apache-2.0",
"description": "Grist is the evolution of spreadsheets",
"homepage": "https://github.com/gristlabs/grist-core",
"repository": "git://github.com/gristlabs/grist-core.git",
"scripts": {
"start": "sandbox/watch.sh",
"install:python": "buildtools/prepare_python.sh",
"install:python2": "buildtools/prepare_python2.sh",
"install:python3": "buildtools/prepare_python3.sh",
"build:prod": "buildtools/build.sh",
"start:prod": "sandbox/run.sh",
"test": "GRIST_SESSION_COOKIE=grist_test_cookie GRIST_TEST_LOGIN=1 TEST_SUPPORT_API_KEY=api_key_for_support TEST_CLEAN_DATABASE=true NODE_PATH=_build:_build/stubs:_build/ext mocha _build/test/nbrowser/*.js _build/test/server/**/*.js _build/test/gen-server/**/*.js",
"test:server": "GRIST_SESSION_COOKIE=grist_test_cookie NODE_PATH=_build:_build/stubs:_build/ext mocha _build/test/server/**/*.js _build/test/gen-server/**/*.js",
"test:smoke": "NODE_PATH=_build:_build/stubs:_build/ext mocha _build/test/nbrowser/Smoke.js",
"test:docker": "./test/test_under_docker.sh"
},
"keywords": [
"grist",
"spreadsheet",
"database"
],
"author": {
"name": "Grist Labs Inc.",
"email": "info@getgrist.com"
},
"private": false,
"devDependencies": {
"@types/accept-language-parser": "1.5.2",
"@types/backbone": "1.3.43",
"@types/chai": "4.1.7",
"@types/chai-as-promised": "7.1.0",
"@types/content-disposition": "0.5.2",
"@types/diff-match-patch": "1.0.32",
"@types/double-ended-queue": "2.1.0",
"@types/express": "4.16.0",
"@types/form-data": "2.2.1",
"@types/fs-extra": "5.0.4",
"@types/image-size": "0.0.29",
"@types/js-yaml": "3.11.2",
"@types/lodash": "4.14.117",
"@types/lru-cache": "5.1.1",
"@types/mime-types": "2.1.0",
"@types/mocha": "5.2.5",
"@types/moment-timezone": "0.5.9",
"@types/node": "^10",
"@types/node-fetch": "2.1.2",
"@types/numeral": "0.0.25",
"@types/pidusage": "2.0.1",
"@types/plotly.js": "1.44.15",
"@types/qrcode": "1.4.2",
"@types/redlock": "3.0.2",
"@types/saml2-js": "2.0.1",
"@types/selenium-webdriver": "4.0.0",
"@types/sqlite3": "3.1.6",
"@types/tmp": "0.0.33",
"@types/uuid": "3.4.4",
"@types/which": "2.0.1",
"app-module-path": "2.2.0",
"catw": "1.0.1",
"chai": "4.2.0",
"chai-as-promised": "7.1.1",
"mocha": "5.2.0",
"mocha-webdriver": "0.2.9",
"moment-locales-webpack-plugin": "^1.2.0",
"nodemon": "^2.0.4",
"otplib": "12.0.1",
"selenium-webdriver": "3.6.0",
"source-map-loader": "^0.2.4",
"stats-webpack-plugin": "^0.7.0",
"tmp-promise": "1.0.5",
"typescript": "3.9.3",
"webpack": "4.41.0",
"webpack-cli": "3.3.2",
"why-is-node-running": "2.0.3"
},
"dependencies": {
"@googleapis/drive": "0.3.1",
"@googleapis/oauth2": "0.2.0",
"@gristlabs/connect-sqlite3": "0.9.11-grist.4",
"@gristlabs/express-session": "1.17.0",
"@gristlabs/moment-guess": "1.2.4-grist.1",
"@gristlabs/pidusage": "2.0.17",
"@gristlabs/sqlite3": "4.1.1-grist.6",
"@popperjs/core": "2.3.3",
"accept-language-parser": "1.5.0",
"async-mutex": "0.2.4",
"axios": "0.18.0",
"backbone": "1.3.3",
"bootstrap": "3.3.5",
"bootstrap-datepicker": "1.9.0",
"bowser": "2.7.0",
"brace": "0.11.1",
"collect-js-deps": "^0.1.1",
"components-jqueryui": "1.12.1",
"connect-redis": "3.4.0",
"cookie-parser": "1.4.3",
"csv": "4.0.0",
"diff-match-patch": "1.0.5",
"double-ended-queue": "2.1.0-0",
"electron": "3.0.7",
"exceljs": "4.2.1",
"express": "4.16.4",
"file-type": "14.1.4",
"fs-extra": "7.0.0",
"grain-rpc": "0.1.7",
"grainjs": "1.0.2",
"highlight.js": "9.13.1",
"i18n-iso-countries": "6.1.0",
"image-size": "0.6.3",
"jquery": "2.2.1",
"js-yaml": "3.12.0",
"knockout": "3.5.0",
"locale-currency": "0.0.2",
"lodash": "4.17.15",
"moment": "2.22.2",
"moment-timezone": "0.5.21",
"morgan": "1.9.1",
"mousetrap": "1.6.2",
"multiparty": "4.2.2",
"node-fetch": "2.2.0",
"numeral": "2.0.6",
"plotly.js-basic-dist": "1.51.1",
"popper-max-size-modifier": "0.2.0",
"popweasel": "0.1.18",
"qrcode": "1.5.0",
"randomcolor": "0.5.3",
"redis": "2.8.0",
"redlock": "3.1.2",
"saml2-js": "2.0.3",
"short-uuid": "3.1.1",
"tmp": "0.0.33",
"ts-interface-checker": "1.0.2",
"typeorm": "0.2.18",
"uuid": "3.3.2",
"winston": "2.4.5",
"ws": "6.1.0"
},
"resolutions": {
"jquery": "2.2.1",
"ts-interface-checker": "1.0.2"
}
}