apiblaze 0.18.2 → 0.18.6
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 +575 -506
- package/dist/react/index.js +377 -178
- package/dist/react/index.mjs +377 -178
- package/dist/server/index.d.mts +29 -0
- package/dist/server/index.d.ts +29 -0
- package/dist/server/index.js +38 -8
- package/dist/server/index.mjs +38 -8
- package/package.json +1 -1
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,18 @@ 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;
|
|
140
|
+
} | {
|
|
141
|
+
action: 'list-admins';
|
|
142
|
+
} | {
|
|
143
|
+
action: 'add-admin';
|
|
144
|
+
email: string;
|
|
145
|
+
} | {
|
|
146
|
+
action: 'remove-admin';
|
|
147
|
+
email: string;
|
|
119
148
|
};
|
|
120
149
|
declare function createApiblazeGroups(cfg: ApiblazeGroupsConfig): {
|
|
121
150
|
handler: (req: Request) => Promise<Response>;
|
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,18 @@ 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;
|
|
140
|
+
} | {
|
|
141
|
+
action: 'list-admins';
|
|
142
|
+
} | {
|
|
143
|
+
action: 'add-admin';
|
|
144
|
+
email: string;
|
|
145
|
+
} | {
|
|
146
|
+
action: 'remove-admin';
|
|
147
|
+
email: string;
|
|
119
148
|
};
|
|
120
149
|
declare function createApiblazeGroups(cfg: ApiblazeGroupsConfig): {
|
|
121
150
|
handler: (req: Request) => Promise<Response>;
|
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,23 @@ 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
|
+
}
|
|
196
|
+
// Tenant-admin allowlist — appoint/remove CO-admins by email. This is the
|
|
197
|
+
// ONLY way admin membership changes (apiblaze_admins is sealed); the plane
|
|
198
|
+
// enforces the guardrails (producer-pinned + last-admin).
|
|
199
|
+
case "list-admins":
|
|
200
|
+
return pass(await iam("GET", "/admin-emails", user, tenant));
|
|
201
|
+
case "add-admin":
|
|
202
|
+
return pass(await iam("POST", "/admin-emails", user, tenant, { email: op.email }));
|
|
203
|
+
case "remove-admin":
|
|
204
|
+
return pass(await iam("DELETE", `/admin-emails/${encodeURIComponent(op.email)}`, user, tenant));
|
|
175
205
|
}
|
|
176
206
|
}
|
|
177
207
|
async function handler(req) {
|
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,23 @@ 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
|
+
}
|
|
168
|
+
// Tenant-admin allowlist — appoint/remove CO-admins by email. This is the
|
|
169
|
+
// ONLY way admin membership changes (apiblaze_admins is sealed); the plane
|
|
170
|
+
// enforces the guardrails (producer-pinned + last-admin).
|
|
171
|
+
case "list-admins":
|
|
172
|
+
return pass(await iam("GET", "/admin-emails", user, tenant));
|
|
173
|
+
case "add-admin":
|
|
174
|
+
return pass(await iam("POST", "/admin-emails", user, tenant, { email: op.email }));
|
|
175
|
+
case "remove-admin":
|
|
176
|
+
return pass(await iam("DELETE", `/admin-emails/${encodeURIComponent(op.email)}`, user, tenant));
|
|
147
177
|
}
|
|
148
178
|
}
|
|
149
179
|
async function handler(req) {
|