nimblybase 0.1.6 → 0.1.7

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/README.md CHANGED
@@ -252,3 +252,9 @@ nimbly sql "select * from notes where id = ?" --param 7
252
252
  go into the statement string: a CLI whose only option is to paste them in
253
253
  teaches everybody — and every agent reading a shell history — to write
254
254
  injectable SQL.
255
+
256
+ Public frontend keys can be issued after browser/device login with
257
+ `nimbly keys create "web frontend" --type anon` (requires `projects:write`).
258
+ They obey row and storage policies. `--type service`, key listing and revocation
259
+ require separate session/PAT key-management authority and remain unavailable
260
+ through OAuth. Never put the agent’s OAuth credential in application code.
package/dist/index.js CHANGED
@@ -373,7 +373,7 @@ function when(iso) {
373
373
 
374
374
  // src/api.ts
375
375
  var DEFAULT_API_URL = "https://api-uat.nimblybase.com";
376
- var VERSION = "0.1.6";
376
+ var VERSION = "0.1.7";
377
377
  function dashboardUrl(api) {
378
378
  const match = /^https:\/\/api(-[a-z0-9]+)?\.(.+)$/.exec(api);
379
379
  return match ? `https://app${match[1] ?? ""}.${match[2]}` : null;
@@ -473,8 +473,8 @@ function createClient(base, token) {
473
473
  resumeProject: (id) => req(`/v1/projects/${id}/resume`, { method: "POST", body: "{}" }),
474
474
  keys: (projectId) => req(`/v1/projects/${projectId}/keys`),
475
475
  createKey: (projectId, input) => req(
476
- `/v1/projects/${projectId}/keys`,
477
- { method: "POST", body: JSON.stringify(input) }
476
+ `/v1/projects/${projectId}/${input.type === "anon" ? "application-keys" : "keys"}`,
477
+ { method: "POST", body: JSON.stringify(input.type === "anon" ? { name: input.name } : input) }
478
478
  ),
479
479
  revokeKey: (keyId) => req(`/v1/keys/${keyId}`, { method: "DELETE" }),
480
480
  // --- project data ---------------------------------------------------
@@ -5585,6 +5585,7 @@ var PendingInvitation = external_exports.object({
5585
5585
  expiresAt: IsoDateTime
5586
5586
  });
5587
5587
  var Me = external_exports.object({
5588
+ authorization: external_exports.object({ via: external_exports.enum(["session", "token", "oauth"]), projectId: external_exports.string().uuid().nullable() }).optional(),
5588
5589
  user: external_exports.object({ id: Uuid, clerkUserId: external_exports.string() }),
5589
5590
  organization: external_exports.object({ id: Uuid, name: external_exports.string(), slug: external_exports.string(), role: Role }).nullable(),
5590
5591
  permissions: external_exports.array(external_exports.string())
@@ -5665,6 +5666,9 @@ var BootstrapBody = external_exports.object({
5665
5666
  }).refine((body) => !(body.planId || body.factsFingerprint) || Boolean(body.name), {
5666
5667
  message: "planId and factsFingerprint are only valid when creating a named project"
5667
5668
  });
5669
+ var CreateApplicationKeyBody = external_exports.object({
5670
+ name: external_exports.string().min(1).max(100)
5671
+ }).strict();
5668
5672
  var CreateApiKeyBody = external_exports.object({
5669
5673
  name: external_exports.string().min(1).max(100),
5670
5674
  type: ApiKeyType
@@ -5866,6 +5870,20 @@ var PendingInvitationListResponse = external_exports.object({ invitations: exter
5866
5870
  var RedeemedInvitationResponse = external_exports.object({
5867
5871
  organization: external_exports.object({ id: Uuid, role: Role })
5868
5872
  });
5873
+ var OAuthConnection = external_exports.object({
5874
+ id: external_exports.string().uuid(),
5875
+ clientId: external_exports.string().uuid(),
5876
+ clientName: external_exports.string(),
5877
+ orgId: external_exports.string().uuid(),
5878
+ projectId: external_exports.string().uuid().nullable(),
5879
+ projectName: external_exports.string().nullable(),
5880
+ scopes: external_exports.array(external_exports.string()),
5881
+ status: external_exports.enum(["ready", "awaiting_exchange"]),
5882
+ connectedAt: external_exports.string().datetime(),
5883
+ expiresAt: external_exports.string().datetime(),
5884
+ lastUsedAt: external_exports.string().datetime().nullable()
5885
+ });
5886
+ var OAuthConnectionListResponse = external_exports.object({ enabled: external_exports.boolean(), connections: external_exports.array(OAuthConnection) });
5869
5887
 
5870
5888
  // ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/Options.js
5871
5889
  var ignoreOverride = Symbol("Let zodToJsonSchema decide on which parser to use");
@@ -6053,6 +6071,34 @@ var routes = {
6053
6071
  // All three are sessionOnly: a token must not be able to mint another
6054
6072
  // token. Otherwise a leaked one manufactures replacements faster than
6055
6073
  // anyone can revoke them, and revoking the one you found achieves nothing.
6074
+ listOAuthConnections: {
6075
+ method: "GET",
6076
+ path: "/v1/me/connections",
6077
+ summary: "Your authorized app connections in this workspace. No credentials.",
6078
+ permission: "org:read",
6079
+ sessionOnly: true,
6080
+ status: 200,
6081
+ response: OAuthConnectionListResponse
6082
+ },
6083
+ narrowOAuthConnection: {
6084
+ method: "POST",
6085
+ path: "/v1/me/connections/{id}/project",
6086
+ summary: "Permanently restrict one authorization to an existing project. Cannot widen or retarget.",
6087
+ permission: "org:read",
6088
+ sessionOnly: true,
6089
+ params: Id,
6090
+ body: external_exports.object({ projectId: external_exports.string().uuid() }).strict(),
6091
+ status: 204
6092
+ },
6093
+ revokeOAuthConnection: {
6094
+ method: "DELETE",
6095
+ path: "/v1/me/connections/{id}",
6096
+ summary: "Disconnect one consent family, including access, refresh and pending exchange.",
6097
+ permission: "org:read",
6098
+ sessionOnly: true,
6099
+ params: Id,
6100
+ status: 204
6101
+ },
6056
6102
  listAccessTokens: {
6057
6103
  method: "GET",
6058
6104
  path: "/v1/me/tokens",
@@ -6216,6 +6262,16 @@ var routes = {
6216
6262
  status: 200,
6217
6263
  response: ApiKeyListResponse
6218
6264
  },
6265
+ createApplicationKey: {
6266
+ method: "POST",
6267
+ path: "/v1/projects/{id}/application-keys",
6268
+ summary: "Issue a public anon application key. It obeys row and storage policies; never issues a service key.",
6269
+ permission: "project:update",
6270
+ params: Id,
6271
+ body: CreateApplicationKeyBody,
6272
+ status: 201,
6273
+ response: IssuedApiKeyResponse
6274
+ },
6219
6275
  createProjectKey: {
6220
6276
  method: "POST",
6221
6277
  path: "/v1/projects/{id}/keys",
@@ -6236,8 +6292,9 @@ var routes = {
6236
6292
  // The platform token never leaves the control plane and expires after 60
6237
6293
  // seconds. Callers are therefore authorized for the operation they asked
6238
6294
  // for (`data:read`, `data:write`, `deploy`, or `logs:read`) rather than for
6239
- // the internal credential used to carry it out. Actual API-key management
6240
- // remains under apikey:* and is deliberately closed to OAuth.
6295
+ // the internal credential used to carry it out. Service-key issuance, key
6296
+ // listing and revocation remain under apikey:* and closed to OAuth. The
6297
+ // separate anon-only application-key route above uses project:update.
6241
6298
  getProjectSchema: {
6242
6299
  method: "GET",
6243
6300
  path: "/v1/projects/{id}/schema",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nimblybase",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "The NimblyBase command line - projects, keys and backends from a terminal.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {