@sasjs/api 0.0.0-stage → 0.2.0
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.
- package/LICENCE.md +21 -0
- package/README.md +87 -2
- package/build/browser.js +2469 -0
- package/build/cjs/corpus/drive.js +288 -0
- package/build/cjs/corpus/runner.js +35 -0
- package/build/cjs/drive/memory-store.js +126 -0
- package/build/cjs/drive/paths.js +82 -0
- package/build/cjs/drive/service.js +143 -0
- package/build/cjs/host/dispatch.js +102 -0
- package/build/cjs/index.js +58 -0
- package/build/cjs/routes/generated.js +1603 -0
- package/build/cjs/routes/index.js +111 -0
- package/build/cjs/routes/overlay.js +75 -0
- package/build/cjs/types.js +35 -0
- package/build/esm/corpus/drive.d.ts +33 -0
- package/build/esm/corpus/drive.d.ts.map +1 -0
- package/build/esm/corpus/drive.js +285 -0
- package/build/esm/corpus/runner.d.ts +27 -0
- package/build/esm/corpus/runner.d.ts.map +1 -0
- package/build/esm/corpus/runner.js +30 -0
- package/build/esm/drive/memory-store.d.ts +37 -0
- package/build/esm/drive/memory-store.d.ts.map +1 -0
- package/build/esm/drive/memory-store.js +122 -0
- package/build/esm/drive/paths.d.ts +49 -0
- package/build/esm/drive/paths.d.ts.map +1 -0
- package/build/esm/drive/paths.js +73 -0
- package/build/esm/drive/service.d.ts +42 -0
- package/build/esm/drive/service.d.ts.map +1 -0
- package/build/esm/drive/service.js +139 -0
- package/build/esm/host/dispatch.d.ts +24 -0
- package/build/esm/host/dispatch.d.ts.map +1 -0
- package/build/esm/host/dispatch.js +98 -0
- package/build/esm/index.d.ts +31 -0
- package/build/esm/index.d.ts.map +1 -0
- package/build/esm/index.js +24 -0
- package/build/esm/package.json +3 -0
- package/build/esm/routes/generated.d.ts +14 -0
- package/build/esm/routes/generated.d.ts.map +1 -0
- package/build/esm/routes/generated.js +1600 -0
- package/build/esm/routes/index.d.ts +18 -0
- package/build/esm/routes/index.d.ts.map +1 -0
- package/build/esm/routes/index.js +106 -0
- package/build/esm/routes/overlay.d.ts +40 -0
- package/build/esm/routes/overlay.d.ts.map +1 -0
- package/build/esm/routes/overlay.js +72 -0
- package/build/esm/types.d.ts +110 -0
- package/build/esm/types.d.ts.map +1 -0
- package/build/esm/types.js +30 -0
- package/package.json +55 -4
package/LICENCE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT Licence
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SASjs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,88 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @sasjs/api
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The SASjs Server API, described once: a route table generated from `sasjs/server`'s published OpenAPI document, the services behind those routes, and a conformance corpus that both the server and the browser build run.
|
|
4
|
+
|
|
5
|
+
It exists because the API was implemented twice.
|
|
6
|
+
`sasjs/server` answers `/SASjsApi/*` from Express controllers, and the browser build in `sasjs/cli` (`sasjs build` with `streamConfig.mockWeb`) answers the same paths from a service worker.
|
|
7
|
+
Two implementations drift: the `webout()` envelope and the session header seed were both found answering differently on the two hosts (`sasjs/cli#1540`, `sasjs/cli#1542`), and neither was caught by a test.
|
|
8
|
+
The plan that this package implements is tracked in `sasjs/cli#1550`.
|
|
9
|
+
|
|
10
|
+
## What is in it
|
|
11
|
+
|
|
12
|
+
**The route table** (`ROUTES`, `findRoute`) is every operation in the API - 43 paths, 60 operations - derived from `spec/swagger.yaml` by `npm run sync:routes`.
|
|
13
|
+
The statuses come from that document and nowhere else: the overlay cannot add one, and an overlay entry naming a status the document does not state fails the build rather than describing a wish.
|
|
14
|
+
The document cannot say everything a host needs, so the reviewed overlay adds the body each response carries, the capability a route needs, and whether this package implements it.
|
|
15
|
+
Where the document is wrong, it is corrected in `sasjs/server` and re-vendored here - never worked around in the overlay.
|
|
16
|
+
|
|
17
|
+
### Regenerating the vendored document
|
|
18
|
+
|
|
19
|
+
`spec/swagger.yaml` is generated from the controllers in `sasjs/server`. In a checkout of that repository run `npm run swagger` (tsoa), copy `api/public/swagger.yaml` over `spec/swagger.yaml` keeping the header at the top of the file, then run `npm run sync:routes` here. `npm run check:routes` fails if `src/routes/generated.ts` no longer matches the document.
|
|
20
|
+
|
|
21
|
+
**The services** (`createDriveService`) are the API's decisions over storage the host supplies: the statuses, the messages, the order of the checks, and the path rules (including `resolveWithinDrive`'s containment).
|
|
22
|
+
They are `async`, take a `DriveStore`, and import nothing - so the same code runs under Express and inside a service worker.
|
|
23
|
+
|
|
24
|
+
**The corpus** (`DRIVE_CORPUS`, `runCase`) is what "the same API" means when a test has to check it: each case is a request, the answer a client expects, and the files it starts from.
|
|
25
|
+
The same cases are meant to run against a live server and against the browser build, so a difference fails a test rather than waiting for a reviewer to notice.
|
|
26
|
+
|
|
27
|
+
## Using it
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install @sasjs/api
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Requires Node `^22.14.0 || >=24.10.0` - the floor the release toolchain needs, and what CI runs.
|
|
34
|
+
|
|
35
|
+
A host supplies a store and, later, an identity.
|
|
36
|
+
In node:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { createDriveService, ROUTES, findRoute } from '@sasjs/api'
|
|
40
|
+
|
|
41
|
+
const drive = createDriveService(nodeDriveStore) // your fs, behind the port
|
|
42
|
+
const match = findRoute('POST', '/SASjsApi/drive/file')
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
In a service worker - the browser build's case - load the bundle the package ships and read it off `self`:
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
importScripts('/host/sasjs-api.js') // build/browser.js, copied by your build
|
|
49
|
+
const { createDriveService, findRoute } = self.SASjsApi
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The bundle is deliberately a classic-worker IIFE: a service worker registered by a static site has `importScripts` and no module loader, and the consumer copies its assets verbatim rather than running a bundler of its own. Bundling belongs here, once.
|
|
53
|
+
|
|
54
|
+
Both hosts answer with the same shapes:
|
|
55
|
+
|
|
56
|
+
- a successful write is `{ status: 'success' }`;
|
|
57
|
+
- a refusal is an `ApiError` carrying `status` and `message`, which a host renders as its own transport requires (`res.status(code).send(...)` on the server, a `Response` in the worker);
|
|
58
|
+
- an operation this package has no handler for is `501`, naming the operation - not a `404` that looks like a typo in the caller;
|
|
59
|
+
- an operation the API does not have is `404`.
|
|
60
|
+
|
|
61
|
+
## Guarantees the build enforces
|
|
62
|
+
|
|
63
|
+
- **No runtime imports.** `src` compiles with `"types": []` and `lib: ES2020`, so a `Buffer`, a `process` or a `document` reference fails `npm run build` rather than a worker at run time. Nothing node-shaped can creep into the browser path.
|
|
64
|
+
- **No Node-only APIs in the published surface.** Storage is a port (`DriveStore`), and `MemoryDriveStore` ships so a host without a filesystem has an implementation to use.
|
|
65
|
+
- **Three builds from one source.** `build/cjs` for node, `build/esm` for a bundler (with `build/esm` marked `"type": "module"` by the build script so Node runs it as ESM), and `build/browser.js` - a classic-worker IIFE that assigns `self.SASjsApi` - for a service worker that has only `importScripts`. CI loads all three.
|
|
66
|
+
- **The table cannot rot silently.** `npm run check:routes` fails when `src/routes/generated.ts` and `spec/swagger.yaml` disagree, and the module throws at import when an overlay entry names an operation the document does not have.
|
|
67
|
+
|
|
68
|
+
## Status
|
|
69
|
+
|
|
70
|
+
Implemented: the nine drive handlers (file read/write/replace/delete, folder read/create/delete, rename, file tree), exercised by 27 corpus cases.
|
|
71
|
+
Not implemented yet, in the order the plan sets: identity (`auth`, `user`, `group`, `permission`, and the `SASLogon` sign-in flow), the session record, program execution (`stp`, `code`), `drive/deploy` and its size cap, and the admin routes.
|
|
72
|
+
`src/routes/overlay.ts` is the list: an operation with `implemented: true` has a handler, and everything else answers `501` with its own name.
|
|
73
|
+
|
|
74
|
+
## Development
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npm ci
|
|
78
|
+
npm test # jest with a coverage floor
|
|
79
|
+
npm run build # dual build + the ESM package marker
|
|
80
|
+
npm run check:routes # the generated table matches spec/swagger.yaml
|
|
81
|
+
npm run lint
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Refreshing the API surface: regenerate `api/public/swagger.yaml` in `sasjs/server` (`npm run swagger`), copy it to `spec/swagger.yaml`, and run `npm run sync:routes`. Review the diff - a new operation needs an overlay entry before a host can say whether it implements it.
|
|
85
|
+
|
|
86
|
+
## Licence
|
|
87
|
+
|
|
88
|
+
MIT. See `LICENCE.md`.
|