6.9 KiB
Data Controller
Contributing
Workflow guidelines
Dependencies that requires licences
To auth for SheetJS Pro version you need to use their private registry
Add client/.npmrc file with following content:
@sheet:registry=https://pylon.sheetjs.com:54111/
//pylon.sheetjs.com:54111/:_authToken="TOKEN-GOES-HERE"
In addition to the registry auth, the @sheet/crypto package is installed from a local tarball
(client/libraries/sheet-crypto.tgz) rather than the registry. This tarball is not committed to
the repo directly - only an encrypted copy is: client/libraries/sheet-crypto.tgz.gpg.
Before running npm i/npm ci in client, you must decrypt it using the passphrase
(stored as the SHEET_PWD CI secret - ask a repo maintainer if you don't have it):
cd client
echo "YOUR_PASSPHRASE" | gpg --batch --yes --passphrase-fd 0 \
--output ./libraries/sheet-crypto.tgz \
--decrypt ./libraries/sheet-crypto.tgz.gpg
npm i
Licence should be inserted in the client/src/index.html file:
<sasjs
...
hotLicenceKey="LICENCE-GOES-HERE"
>
</sasjs>
Development
Update client/src/index.html so that it points to your SAS9, SASVIYA or SASJS backend.
Be aware that VIYA can be configured in such way that it would not work with cross origin frontend.
Follow this guide to disable CORS: https://sasjs.io/cors/ (NOTICE: Sometimes even this approach would fail to work, in such case it is imposible to set it up without reconfiguring the VIYA server)
Start dev server:
cd client
npm start
Mocked backend (frontend development without SAS)
Data Controller ships a full set of JS mock services under sas/mocks/sasjs/ that mimic the SAS backend using SASjs Server in JS-only mode. This lets you run the entire frontend (editor grid, approvals, viewer, admin, Excel maps, etc.) without a SAS licence or SAS server. The Cypress E2E tests and Lighthouse CI both run against this setup.
Prerequisites
- Node.js (same version used for the frontend build)
- The frontend dependencies installed (
cd client && npm ciafter decrypting sheet-crypto as described above)
1. Start SASjs Server
Download the latest Linux (or macOS/Windows) binary from SASjs Server releases, unzip it, and create a .env file alongside the executable:
RUN_TIMES=js
NODE_PATH=node
CORS=enable
WHITELIST=http://localhost:4200
RUN_TIMES=js means the server executes .js files as Stored Programs (no SAS binary needed). CORS=enable plus WHITELIST allows the Angular dev server on port 4200 to call the mock services on port 5000. Start the server:
./api-linux # or api-macos / api-win.exe depending on your platform
The server runs in desktop mode (no auth) on http://localhost:5000 by default.
2. Deploy the mock services and streaming frontend
From sas/mocks/sasjs/:
npm ci
sasjs cbd -t server-ci
This compiles, builds, and deploys the JS mock services plus the Angular frontend (as a streaming app) to the SASjs Server. The server-ci target in sas/mocks/sasjs/sasjsconfig.json points to http://localhost:5000 with appLoc /Public/app/dc and stream service name clickme.
After deploy, the streamed app is available at: http://localhost:5000/AppStream/clickme/
3. Run the Angular dev server (optional, for hot reload)
For frontend development with live reload, point client/src/index.html at the local SASjs Server and start the dev server:
cd client
# Edit src/index.html: set serverUrl="http://localhost:5000", appLoc="/Public/app/dc", serverType="SASJS"
npm start
The app will be at http://localhost:4200. It calls the JS mock services on port 5000 via the SASjs adapter (CORS is enabled by the .env above).
How the mocks work
Each .js file in sas/mocks/sasjs/services/ corresponds to a real SAS service (e.g. public/startupservice.js mimics services/public/startupservice.sas). The JS runtime predeclares fs and _webout; the mock assigns a JSON string to _webout that matches the structure the real SAS service would return. Some mocks are stateful: they persist data to a mock-storage/ folder on the SASjs Drive (e.g. licence.json, users.json, filter.txt) using the predeclared fs module.
The mock data includes sample tables (DC996664.MPE_X_TEST, MPE_X_NEW, MPE_X_FORMULA_TEST, etc.) with realistic columns, validation rules (HARDREGEX, SOFTREGEX, HARDSELECT, READONLY, HIDDEN, ROUND, NUMBER_FORMAT), and dropdown values. This is sufficient to exercise the full editor grid, approval workflow, viewer, and admin screens.
There is also a SAS 9 mock variant under sas/mocks/sas9/ (target sas9-mocks) that mimics SAS 9 stored processes with the same JS approach but a different appLoc (/User Folders/sasdemo/).
Re-deploying after changes
After changing mock services, re-run sasjs cbd -t server-ci from sas/mocks/sasjs/. After changing the frontend, rebuild (cd client && npm run build) then re-deploy so the streaming app picks up the new client/dist/. If you are using ng serve (step 3), only the mock services need re-deploying; the frontend hot-reloads automatically.
GUI Elements
For documentation on the Clarity Design System, including a list of components and example usage, see our website.
Code style
Run prettier fix:
npm run lint:fix
Generate docs
Typedoc is used for generating typescript documentation based on the code. That part is automated and beign done as a part of CI job.
Release
Release is automated as a part of CI job. Workflow file: .gitea/workflows/release.yaml.
It will run automatically when branch merged to the main branch.
IMPORTANT!
If release job fails, after it has been created empty release and a tag, we must not re-run the relase job until we removed the newly create GIT TAG and RELEASE.
To remove the git tag run:
git push -d origin vX.X.X
To remove the release, you need to do it with repo administration over at https://git.datacontroller.io/dc/dc
Troubleshooting
npm i fails with ENOENT on sheet-crypto.tgz
If npm i/npm ci in client fails with:
npm error enoent ENOENT: no such file or directory, open '.../client/libraries/sheet-crypto.tgz'
it means the encrypted sheet-crypto.tgz.gpg hasn't been decrypted yet. See
Dependencies that requires licences above for how to decrypt it.
Makedata service "could not create directory" error
The dcpath folder should have its permissions set so that the system account (SYSUSERID) can both read and write to it.
Example:
If dcpath is: '/tmp/dc'
Run:
chmod 777 /tmp/dc