@raybase/api 0.0.2 → 0.1.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/LICENSE +21 -0
- package/dist/admin-routes.d.ts +11 -0
- package/dist/admin-routes.d.ts.map +1 -0
- package/dist/admin-routes.js +208 -0
- package/dist/admin-routes.js.map +1 -0
- package/dist/api.d.ts +102 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +375 -0
- package/dist/api.js.map +1 -0
- package/dist/auth.d.ts +87 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +377 -0
- package/dist/auth.js.map +1 -0
- package/dist/crypto.d.ts +14 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +59 -0
- package/dist/crypto.js.map +1 -0
- package/dist/errors.d.ts +9 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +26 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated/admin-assets.d.ts +5 -0
- package/dist/generated/admin-assets.d.ts.map +1 -0
- package/dist/generated/admin-assets.js +5 -0
- package/dist/generated/admin-assets.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/path.d.ts +2 -0
- package/dist/path.d.ts.map +1 -0
- package/dist/path.js +25 -0
- package/dist/path.js.map +1 -0
- package/dist/system-tables.d.ts +6 -0
- package/dist/system-tables.d.ts.map +1 -0
- package/dist/system-tables.js +65 -0
- package/dist/system-tables.js.map +1 -0
- package/package.json +36 -8
- package/skills/raybase-api/SKILL.md +45 -0
- package/templates/react-router/app/api/operations.ts +8 -0
- package/templates/tanstack-start/src/api/operations.ts +15 -0
- package/README.md +0 -3
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { id, longText, raybaseSystemTable, text } from "@raybase/core";
|
|
2
|
+
export const apiKeysTableName = "_api_keys";
|
|
3
|
+
export const apiServicePrincipalsTableName = "_api_service_principals";
|
|
4
|
+
export const apiKeyEventsTableName = "_api_key_events";
|
|
5
|
+
export const raybaseApiSystemTables = [
|
|
6
|
+
raybaseSystemTable(apiServicePrincipalsTableName, {
|
|
7
|
+
id: id(),
|
|
8
|
+
label: text({ required: true }),
|
|
9
|
+
description: longText(),
|
|
10
|
+
ownerUserId: text({ required: true }),
|
|
11
|
+
defaultScopesJson: longText({ required: true }),
|
|
12
|
+
disabledAt: text(),
|
|
13
|
+
createdBy: text(),
|
|
14
|
+
createdAt: text({ required: true }),
|
|
15
|
+
updatedAt: text({ required: true })
|
|
16
|
+
}, {
|
|
17
|
+
label: "API service principals",
|
|
18
|
+
indexes: [["ownerUserId", "updatedAt"], ["disabledAt"]]
|
|
19
|
+
}),
|
|
20
|
+
raybaseSystemTable(apiKeysTableName, {
|
|
21
|
+
id: id(),
|
|
22
|
+
name: text({ required: true }),
|
|
23
|
+
description: longText(),
|
|
24
|
+
servicePrincipalId: text({ required: true }),
|
|
25
|
+
ownerUserId: text({ required: true }),
|
|
26
|
+
principalLabel: text({ required: true }),
|
|
27
|
+
prefix: text({ required: true, unique: true }),
|
|
28
|
+
hash: text({ required: true }),
|
|
29
|
+
scopesJson: longText({ required: true }),
|
|
30
|
+
expiresAt: text(),
|
|
31
|
+
revokedAt: text(),
|
|
32
|
+
revokedBy: text(),
|
|
33
|
+
revokedReason: longText(),
|
|
34
|
+
createdBy: text(),
|
|
35
|
+
createdAt: text({ required: true }),
|
|
36
|
+
rotatedAt: text(),
|
|
37
|
+
lastUsedAt: text(),
|
|
38
|
+
lastUsedIpHash: text(),
|
|
39
|
+
lastUsedUserAgent: text()
|
|
40
|
+
}, {
|
|
41
|
+
label: "API keys",
|
|
42
|
+
indexes: [
|
|
43
|
+
{ columns: ["prefix"], unique: true },
|
|
44
|
+
["servicePrincipalId", "createdAt"],
|
|
45
|
+
["ownerUserId", "createdAt"],
|
|
46
|
+
["revokedAt"],
|
|
47
|
+
["lastUsedAt"]
|
|
48
|
+
]
|
|
49
|
+
}),
|
|
50
|
+
raybaseSystemTable(apiKeyEventsTableName, {
|
|
51
|
+
id: id(),
|
|
52
|
+
keyId: text({ required: true }),
|
|
53
|
+
servicePrincipalId: text(),
|
|
54
|
+
ownerUserId: text(),
|
|
55
|
+
event: text({ required: true }),
|
|
56
|
+
actorUserId: text(),
|
|
57
|
+
requestId: text(),
|
|
58
|
+
metadataJson: longText(),
|
|
59
|
+
createdAt: text({ required: true })
|
|
60
|
+
}, {
|
|
61
|
+
label: "API key events",
|
|
62
|
+
indexes: [["keyId", "createdAt"], ["servicePrincipalId", "createdAt"], ["event", "createdAt"]]
|
|
63
|
+
})
|
|
64
|
+
];
|
|
65
|
+
//# sourceMappingURL=system-tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-tables.js","sourceRoot":"","sources":["../src/system-tables.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,16 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raybase/api",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "
|
|
5
|
-
"license": "
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Optional first-party Raybase API key and external JSON API module.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"templates",
|
|
18
|
+
"skills"
|
|
19
|
+
],
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@raybase/core": "0.3.3"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/react": "^18.3.27",
|
|
25
|
+
"@types/react-dom": "^18.3.7",
|
|
26
|
+
"esbuild": "^0.25.12",
|
|
27
|
+
"react": "^18.3.1",
|
|
28
|
+
"react-dom": "^18.3.1",
|
|
29
|
+
"typescript": "^5.8.3",
|
|
30
|
+
"@raybase/core": "0.3.3"
|
|
31
|
+
},
|
|
6
32
|
"repository": {
|
|
7
33
|
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/raybasedev/raybase.git"
|
|
34
|
+
"url": "git+https://github.com/raybasedev/raybase.git",
|
|
35
|
+
"directory": "packages/api"
|
|
9
36
|
},
|
|
10
37
|
"publishConfig": {
|
|
11
38
|
"access": "public"
|
|
12
39
|
},
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
}
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "node scripts/build-admin.mjs && tsc -p tsconfig.json",
|
|
42
|
+
"check": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.admin.json"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: raybase-api
|
|
3
|
+
description: Expose selected Raybase actions through the optional @raybase/api module with API keys and scopes.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Raybase API
|
|
7
|
+
|
|
8
|
+
Use this skill before adding or changing an app's external HTTP API surface.
|
|
9
|
+
|
|
10
|
+
## Rules
|
|
11
|
+
|
|
12
|
+
- Declare business behavior as `defineAction()` first.
|
|
13
|
+
- Read `.agents/skills/raybase-actions/SKILL.md` for action declaration,
|
|
14
|
+
policy, row authorization, idempotency, annotations, and adapter guidance.
|
|
15
|
+
- Every action exposed through `apiOperation()` must declare `output`;
|
|
16
|
+
`raybase doctor` fails external API routes whose linked action has no output
|
|
17
|
+
schema.
|
|
18
|
+
- Expose only intentional actions with `apiOperation(action, ...)`.
|
|
19
|
+
- Do not add API route handlers with business logic.
|
|
20
|
+
- Keep API scopes separate from action policies. A key scope answers whether the key may call an operation; the action policy still decides whether the linked user may perform the work.
|
|
21
|
+
- Do not expose actions marked `requiresInternalControl`.
|
|
22
|
+
- Use resource scopes such as `tasks:read`, `tasks:write`, and `tasks:delete`.
|
|
23
|
+
- API keys execute as existing Raybase users. Do not bypass policies with raw SQL or service executors.
|
|
24
|
+
- Treat `RAYBASE_API_KEY_SECRET` as a long-lived production secret. In v1, changing it invalidates existing API keys because stored key hashes are HMAC-based.
|
|
25
|
+
|
|
26
|
+
## Example
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { apiModule, apiOperation, defineApiOperations } from "@raybase/api";
|
|
30
|
+
import { actions } from "../actions";
|
|
31
|
+
|
|
32
|
+
export const api = apiModule({
|
|
33
|
+
prefix: "/api/v1",
|
|
34
|
+
operations: defineApiOperations({
|
|
35
|
+
completeTask: apiOperation(actions.completeTask, {
|
|
36
|
+
method: "POST",
|
|
37
|
+
path: "/tasks/:id/complete",
|
|
38
|
+
scopes: ["tasks:write"],
|
|
39
|
+
parseRequest: ({ params, body }) => ({ id: params.id, ...(body as object) })
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Pass the exported module to `createRaybaseApp({ modules: [api] })`.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { apiModule, defineApiOperations } from "@raybase/api";
|
|
2
|
+
|
|
3
|
+
// Add external API operations by adapting declared Raybase actions with
|
|
4
|
+
// apiOperation(action, { method, path, scopes, parseRequest }).
|
|
5
|
+
export const api = apiModule({
|
|
6
|
+
prefix: "/api/v1",
|
|
7
|
+
operations: defineApiOperations({})
|
|
8
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { apiModule, apiOperation, defineApiOperations } from "@raybase/api";
|
|
2
|
+
import { actions } from "../actions";
|
|
3
|
+
|
|
4
|
+
export const api = apiModule({
|
|
5
|
+
prefix: "/api/v1",
|
|
6
|
+
operations: defineApiOperations({
|
|
7
|
+
markTodoDone: apiOperation(actions.markTodoDone, {
|
|
8
|
+
method: "POST",
|
|
9
|
+
path: "/todos/:id/done",
|
|
10
|
+
scopes: ["todos:write"],
|
|
11
|
+
summary: "Mark todo done",
|
|
12
|
+
parseRequest: ({ params }) => ({ id: params.id })
|
|
13
|
+
})
|
|
14
|
+
})
|
|
15
|
+
});
|
package/README.md
DELETED