@raybase/api 0.0.0 → 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.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/dist/admin-routes.d.ts +11 -0
  3. package/dist/admin-routes.d.ts.map +1 -0
  4. package/dist/admin-routes.js +208 -0
  5. package/dist/admin-routes.js.map +1 -0
  6. package/dist/api.d.ts +102 -0
  7. package/dist/api.d.ts.map +1 -0
  8. package/dist/api.js +375 -0
  9. package/dist/api.js.map +1 -0
  10. package/dist/auth.d.ts +87 -0
  11. package/dist/auth.d.ts.map +1 -0
  12. package/dist/auth.js +377 -0
  13. package/dist/auth.js.map +1 -0
  14. package/dist/crypto.d.ts +14 -0
  15. package/dist/crypto.d.ts.map +1 -0
  16. package/dist/crypto.js +59 -0
  17. package/dist/crypto.js.map +1 -0
  18. package/dist/errors.d.ts +9 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +26 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/generated/admin-assets.d.ts +5 -0
  23. package/dist/generated/admin-assets.d.ts.map +1 -0
  24. package/dist/generated/admin-assets.js +5 -0
  25. package/dist/generated/admin-assets.js.map +1 -0
  26. package/dist/index.d.ts +6 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +6 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/path.d.ts +2 -0
  31. package/dist/path.d.ts.map +1 -0
  32. package/dist/path.js +25 -0
  33. package/dist/path.js.map +1 -0
  34. package/dist/system-tables.d.ts +6 -0
  35. package/dist/system-tables.d.ts.map +1 -0
  36. package/dist/system-tables.js +65 -0
  37. package/dist/system-tables.js.map +1 -0
  38. package/package.json +36 -8
  39. package/skills/raybase-api/SKILL.md +45 -0
  40. package/templates/react-router/app/api/operations.ts +8 -0
  41. package/templates/tanstack-start/src/api/operations.ts +15 -0
  42. 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.0",
4
- "description": "Reserved for Raybase. Nothing is released under this name yet.",
5
- "license": "UNLICENSED",
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
- "files": [
14
- "README.md"
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
@@ -1,3 +0,0 @@
1
- # @raybase/api
2
-
3
- This name is reserved for Raybase. Nothing is released under it yet, and this package holds no code.