apiblaze 0.18.3 → 0.18.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/dist/index.js +583 -507
- package/dist/react/index.js +366 -233
- package/dist/react/index.mjs +366 -233
- package/dist/server/index.d.mts +21 -0
- package/dist/server/index.d.ts +21 -0
- package/dist/server/index.js +29 -8
- package/dist/server/index.mjs +29 -8
- package/package.json +3 -3
package/dist/server/index.d.mts
CHANGED
|
@@ -73,6 +73,23 @@ interface ApiblazeGroupsConfig {
|
|
|
73
73
|
}
|
|
74
74
|
type GroupsAction = {
|
|
75
75
|
action: 'snapshot';
|
|
76
|
+
} | {
|
|
77
|
+
action: 'list-groups';
|
|
78
|
+
offset?: number;
|
|
79
|
+
q?: string;
|
|
80
|
+
} | {
|
|
81
|
+
action: 'search-users';
|
|
82
|
+
q?: string;
|
|
83
|
+
limit?: number;
|
|
84
|
+
offset?: number;
|
|
85
|
+
} | {
|
|
86
|
+
action: 'list-observed';
|
|
87
|
+
offset?: number;
|
|
88
|
+
q?: string;
|
|
89
|
+
} | {
|
|
90
|
+
action: 'group-members';
|
|
91
|
+
groupId: string;
|
|
92
|
+
offset?: number;
|
|
76
93
|
} | {
|
|
77
94
|
action: 'create-group';
|
|
78
95
|
name: string;
|
|
@@ -116,6 +133,10 @@ type GroupsAction = {
|
|
|
116
133
|
email?: string;
|
|
117
134
|
displayName?: string;
|
|
118
135
|
groups?: string[];
|
|
136
|
+
} | {
|
|
137
|
+
action: 'create-user';
|
|
138
|
+
ref: string;
|
|
139
|
+
displayName?: string;
|
|
119
140
|
} | {
|
|
120
141
|
action: 'list-admins';
|
|
121
142
|
} | {
|
package/dist/server/index.d.ts
CHANGED
|
@@ -73,6 +73,23 @@ interface ApiblazeGroupsConfig {
|
|
|
73
73
|
}
|
|
74
74
|
type GroupsAction = {
|
|
75
75
|
action: 'snapshot';
|
|
76
|
+
} | {
|
|
77
|
+
action: 'list-groups';
|
|
78
|
+
offset?: number;
|
|
79
|
+
q?: string;
|
|
80
|
+
} | {
|
|
81
|
+
action: 'search-users';
|
|
82
|
+
q?: string;
|
|
83
|
+
limit?: number;
|
|
84
|
+
offset?: number;
|
|
85
|
+
} | {
|
|
86
|
+
action: 'list-observed';
|
|
87
|
+
offset?: number;
|
|
88
|
+
q?: string;
|
|
89
|
+
} | {
|
|
90
|
+
action: 'group-members';
|
|
91
|
+
groupId: string;
|
|
92
|
+
offset?: number;
|
|
76
93
|
} | {
|
|
77
94
|
action: 'create-group';
|
|
78
95
|
name: string;
|
|
@@ -116,6 +133,10 @@ type GroupsAction = {
|
|
|
116
133
|
email?: string;
|
|
117
134
|
displayName?: string;
|
|
118
135
|
groups?: string[];
|
|
136
|
+
} | {
|
|
137
|
+
action: 'create-user';
|
|
138
|
+
ref: string;
|
|
139
|
+
displayName?: string;
|
|
119
140
|
} | {
|
|
120
141
|
action: 'list-admins';
|
|
121
142
|
} | {
|
package/dist/server/index.js
CHANGED
|
@@ -89,7 +89,14 @@ function createPlaneCore(cfg) {
|
|
|
89
89
|
function createApiblazeGroups(cfg) {
|
|
90
90
|
if (typeof cfg.getUser !== "function") throw new Error("apiblaze: getUser is required \u2014 map your session to { tenant, userId, email }.");
|
|
91
91
|
const core = createPlaneCore({ cpKey: cfg.cpKey, apikeysBase: cfg.base, iamBase: cfg.iamBase });
|
|
92
|
-
const iam = (method, path, user, tenant, body) => core.planeFetch(core.iamBase, method, `/v1/admin${path}`, user, { query: { tenant }, body });
|
|
92
|
+
const iam = (method, path, user, tenant, body, query) => core.planeFetch(core.iamBase, method, `/v1/admin${path}`, user, { query: { tenant, ...query ?? {} }, body });
|
|
93
|
+
const paging = (o) => {
|
|
94
|
+
const p = {};
|
|
95
|
+
if (typeof o.limit === "number") p.limit = String(o.limit);
|
|
96
|
+
if (typeof o.offset === "number") p.offset = String(o.offset);
|
|
97
|
+
if (o.q != null && o.q !== "") p.q = o.q;
|
|
98
|
+
return p;
|
|
99
|
+
};
|
|
93
100
|
async function context(user) {
|
|
94
101
|
const tenant = await core.resolveTenant(user);
|
|
95
102
|
await core.ensureEndUser(user, tenant);
|
|
@@ -102,22 +109,28 @@ function createApiblazeGroups(cfg) {
|
|
|
102
109
|
async function run(user, op) {
|
|
103
110
|
const { tenant } = await context(user);
|
|
104
111
|
if (op.action === "snapshot") {
|
|
105
|
-
const [groupsRes,
|
|
106
|
-
iam("GET", "/groups", user, tenant),
|
|
107
|
-
iam("GET", "/
|
|
108
|
-
iam("GET", "/observed-identities", user, tenant)
|
|
112
|
+
const [groupsRes, observedRes] = await Promise.all([
|
|
113
|
+
iam("GET", "/groups", user, tenant, void 0, { limit: "25" }),
|
|
114
|
+
iam("GET", "/observed-identities", user, tenant, void 0, { limit: "1" })
|
|
109
115
|
]);
|
|
110
|
-
if (groupsRes.status === 403) return { status: 200, data: { access: "pending", email: user.email ?? null, groups: [],
|
|
116
|
+
if (groupsRes.status === 403) return { status: 200, data: { access: "pending", email: user.email ?? null, groups: [], groupTotal: 0, observedNew: 0 } };
|
|
111
117
|
if (!groupsRes.ok) return { status: groupsRes.status, data: { error: await safeErr(groupsRes) } };
|
|
112
118
|
const g = await groupsRes.json();
|
|
113
|
-
const u = usersRes.ok ? await usersRes.json() : { users: [] };
|
|
114
119
|
const o = observedRes.ok ? await observedRes.json() : {};
|
|
115
120
|
return {
|
|
116
121
|
status: 200,
|
|
117
|
-
data: { access: "ok", groups: g.groups ?? [],
|
|
122
|
+
data: { access: "ok", groups: g.groups ?? [], groupTotal: g.total ?? (g.groups?.length ?? 0), observedNew: o.total ?? 0 }
|
|
118
123
|
};
|
|
119
124
|
}
|
|
120
125
|
switch (op.action) {
|
|
126
|
+
case "list-groups":
|
|
127
|
+
return pass(await iam("GET", "/groups", user, tenant, void 0, paging({ limit: 25, offset: op.offset, q: op.q })));
|
|
128
|
+
case "search-users":
|
|
129
|
+
return pass(await iam("GET", "/users", user, tenant, void 0, paging({ limit: op.limit ?? 20, offset: op.offset, q: op.q })));
|
|
130
|
+
case "list-observed":
|
|
131
|
+
return pass(await iam("GET", "/observed-identities", user, tenant, void 0, paging({ limit: 25, offset: op.offset, q: op.q })));
|
|
132
|
+
case "group-members":
|
|
133
|
+
return pass(await iam("GET", `/groups/${encodeURIComponent(op.groupId)}`, user, tenant, void 0, paging({ limit: 50, offset: op.offset })));
|
|
121
134
|
case "group-detail": {
|
|
122
135
|
const [detail, subs] = await Promise.all([
|
|
123
136
|
iam("GET", `/groups/${encodeURIComponent(op.groupId)}`, user, tenant),
|
|
@@ -172,6 +185,14 @@ function createApiblazeGroups(cfg) {
|
|
|
172
185
|
display_name: op.displayName,
|
|
173
186
|
groups: op.groups ?? []
|
|
174
187
|
}));
|
|
188
|
+
case "create-user": {
|
|
189
|
+
const ref = (op.ref ?? "").trim();
|
|
190
|
+
if (!ref) return { status: 400, data: { error: "Enter an email or a user id" } };
|
|
191
|
+
if (ref.includes("@")) {
|
|
192
|
+
return pass(await iam("POST", "/users", user, tenant, { email: ref, display_name: op.displayName }));
|
|
193
|
+
}
|
|
194
|
+
return pass(await iam("POST", "/identities/upsert", user, tenant, { consumer_user_id: ref, display_name: op.displayName }));
|
|
195
|
+
}
|
|
175
196
|
// Tenant-admin allowlist — appoint/remove CO-admins by email. This is the
|
|
176
197
|
// ONLY way admin membership changes (apiblaze_admins is sealed); the plane
|
|
177
198
|
// enforces the guardrails (producer-pinned + last-admin).
|
package/dist/server/index.mjs
CHANGED
|
@@ -61,7 +61,14 @@ function createPlaneCore(cfg) {
|
|
|
61
61
|
function createApiblazeGroups(cfg) {
|
|
62
62
|
if (typeof cfg.getUser !== "function") throw new Error("apiblaze: getUser is required \u2014 map your session to { tenant, userId, email }.");
|
|
63
63
|
const core = createPlaneCore({ cpKey: cfg.cpKey, apikeysBase: cfg.base, iamBase: cfg.iamBase });
|
|
64
|
-
const iam = (method, path, user, tenant, body) => core.planeFetch(core.iamBase, method, `/v1/admin${path}`, user, { query: { tenant }, body });
|
|
64
|
+
const iam = (method, path, user, tenant, body, query) => core.planeFetch(core.iamBase, method, `/v1/admin${path}`, user, { query: { tenant, ...query ?? {} }, body });
|
|
65
|
+
const paging = (o) => {
|
|
66
|
+
const p = {};
|
|
67
|
+
if (typeof o.limit === "number") p.limit = String(o.limit);
|
|
68
|
+
if (typeof o.offset === "number") p.offset = String(o.offset);
|
|
69
|
+
if (o.q != null && o.q !== "") p.q = o.q;
|
|
70
|
+
return p;
|
|
71
|
+
};
|
|
65
72
|
async function context(user) {
|
|
66
73
|
const tenant = await core.resolveTenant(user);
|
|
67
74
|
await core.ensureEndUser(user, tenant);
|
|
@@ -74,22 +81,28 @@ function createApiblazeGroups(cfg) {
|
|
|
74
81
|
async function run(user, op) {
|
|
75
82
|
const { tenant } = await context(user);
|
|
76
83
|
if (op.action === "snapshot") {
|
|
77
|
-
const [groupsRes,
|
|
78
|
-
iam("GET", "/groups", user, tenant),
|
|
79
|
-
iam("GET", "/
|
|
80
|
-
iam("GET", "/observed-identities", user, tenant)
|
|
84
|
+
const [groupsRes, observedRes] = await Promise.all([
|
|
85
|
+
iam("GET", "/groups", user, tenant, void 0, { limit: "25" }),
|
|
86
|
+
iam("GET", "/observed-identities", user, tenant, void 0, { limit: "1" })
|
|
81
87
|
]);
|
|
82
|
-
if (groupsRes.status === 403) return { status: 200, data: { access: "pending", email: user.email ?? null, groups: [],
|
|
88
|
+
if (groupsRes.status === 403) return { status: 200, data: { access: "pending", email: user.email ?? null, groups: [], groupTotal: 0, observedNew: 0 } };
|
|
83
89
|
if (!groupsRes.ok) return { status: groupsRes.status, data: { error: await safeErr(groupsRes) } };
|
|
84
90
|
const g = await groupsRes.json();
|
|
85
|
-
const u = usersRes.ok ? await usersRes.json() : { users: [] };
|
|
86
91
|
const o = observedRes.ok ? await observedRes.json() : {};
|
|
87
92
|
return {
|
|
88
93
|
status: 200,
|
|
89
|
-
data: { access: "ok", groups: g.groups ?? [],
|
|
94
|
+
data: { access: "ok", groups: g.groups ?? [], groupTotal: g.total ?? (g.groups?.length ?? 0), observedNew: o.total ?? 0 }
|
|
90
95
|
};
|
|
91
96
|
}
|
|
92
97
|
switch (op.action) {
|
|
98
|
+
case "list-groups":
|
|
99
|
+
return pass(await iam("GET", "/groups", user, tenant, void 0, paging({ limit: 25, offset: op.offset, q: op.q })));
|
|
100
|
+
case "search-users":
|
|
101
|
+
return pass(await iam("GET", "/users", user, tenant, void 0, paging({ limit: op.limit ?? 20, offset: op.offset, q: op.q })));
|
|
102
|
+
case "list-observed":
|
|
103
|
+
return pass(await iam("GET", "/observed-identities", user, tenant, void 0, paging({ limit: 25, offset: op.offset, q: op.q })));
|
|
104
|
+
case "group-members":
|
|
105
|
+
return pass(await iam("GET", `/groups/${encodeURIComponent(op.groupId)}`, user, tenant, void 0, paging({ limit: 50, offset: op.offset })));
|
|
93
106
|
case "group-detail": {
|
|
94
107
|
const [detail, subs] = await Promise.all([
|
|
95
108
|
iam("GET", `/groups/${encodeURIComponent(op.groupId)}`, user, tenant),
|
|
@@ -144,6 +157,14 @@ function createApiblazeGroups(cfg) {
|
|
|
144
157
|
display_name: op.displayName,
|
|
145
158
|
groups: op.groups ?? []
|
|
146
159
|
}));
|
|
160
|
+
case "create-user": {
|
|
161
|
+
const ref = (op.ref ?? "").trim();
|
|
162
|
+
if (!ref) return { status: 400, data: { error: "Enter an email or a user id" } };
|
|
163
|
+
if (ref.includes("@")) {
|
|
164
|
+
return pass(await iam("POST", "/users", user, tenant, { email: ref, display_name: op.displayName }));
|
|
165
|
+
}
|
|
166
|
+
return pass(await iam("POST", "/identities/upsert", user, tenant, { consumer_user_id: ref, display_name: op.displayName }));
|
|
167
|
+
}
|
|
147
168
|
// Tenant-admin allowlist — appoint/remove CO-admins by email. This is the
|
|
148
169
|
// ONLY way admin membership changes (apiblaze_admins is sealed); the plane
|
|
149
170
|
// enforces the guardrails (producer-pinned + last-admin).
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apiblaze",
|
|
3
|
-
"version": "0.18.
|
|
4
|
-
"description": "APIblaze CLI
|
|
3
|
+
"version": "0.18.7",
|
|
4
|
+
"description": "APIblaze CLI \u2014 Chat with your APIs, Manage your API keys, users and groups with the APIblaze serverless proxy",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"apiblaze",
|
|
7
7
|
"dev-tunnel",
|
|
@@ -90,4 +90,4 @@
|
|
|
90
90
|
"optional": true
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
-
}
|
|
93
|
+
}
|