@absolutejs/absolute 0.19.0-beta.1048 → 0.19.0-beta.1049

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.
@@ -1113,6 +1113,134 @@ var require_jsx_dev_runtime = __commonJS((exports, module) => {
1113
1113
  }
1114
1114
  });
1115
1115
 
1116
+ // src/cli/config/auth/authCatalog.ts
1117
+ var AUTH_CORE_ROUTES, AUTH_FEATURES;
1118
+ var init_authCatalog = __esm(() => {
1119
+ AUTH_CORE_ROUTES = [
1120
+ "authorize",
1121
+ "callback",
1122
+ "profile",
1123
+ "status",
1124
+ "signout",
1125
+ "refresh",
1126
+ "revoke"
1127
+ ];
1128
+ AUTH_FEATURES = [
1129
+ {
1130
+ blurb: "Email/password \u2014 register, verify-email, login, reset-password \u2014 minting the same session as OAuth.",
1131
+ configKey: "credentials",
1132
+ id: "credentials",
1133
+ kind: "routes",
1134
+ label: "Credentials"
1135
+ },
1136
+ {
1137
+ blurb: "Magic links + email/SMS one-time codes; each verify route mints the same session as every other flow.",
1138
+ configKey: "passwordless",
1139
+ id: "passwordless",
1140
+ kind: "routes",
1141
+ label: "Passwordless"
1142
+ },
1143
+ {
1144
+ blurb: "TOTP + backup codes; auto-wires the login MFA gate over credentials and mounts enroll/challenge routes.",
1145
+ configKey: "mfa",
1146
+ id: "mfa",
1147
+ kind: "routes",
1148
+ label: "MFA"
1149
+ },
1150
+ {
1151
+ blurb: "Passkeys (WebAuthn): registration ceremony for the caller + passwordless authentication ceremony.",
1152
+ configKey: "webauthn",
1153
+ id: "webauthn",
1154
+ kind: "routes",
1155
+ label: "WebAuthn / passkeys"
1156
+ },
1157
+ {
1158
+ blurb: "Per-organization enterprise SSO (OIDC + SAML); id_tokens verified in-house against the issuer JWKS.",
1159
+ configKey: "sso",
1160
+ id: "sso",
1161
+ kind: "routes",
1162
+ label: "Enterprise SSO"
1163
+ },
1164
+ {
1165
+ blurb: "SCIM 2.0 directory provisioning (Okta / Azure AD) with per-org bearer-token auth.",
1166
+ configKey: "scim",
1167
+ id: "scim",
1168
+ kind: "routes",
1169
+ label: "SCIM provisioning"
1170
+ },
1171
+ {
1172
+ blurb: "First-class multi-tenancy: orgs, memberships, invitations, and org-scoped roles.",
1173
+ configKey: "organizations",
1174
+ id: "organizations",
1175
+ kind: "routes",
1176
+ label: "Organizations"
1177
+ },
1178
+ {
1179
+ blurb: "Org-scoped roles & permissions \u2014 list an org\u2019s roles and set a member\u2019s roles.",
1180
+ configKey: "roles",
1181
+ id: "roles",
1182
+ kind: "routes",
1183
+ label: "Roles & permissions"
1184
+ },
1185
+ {
1186
+ blurb: "Headless admin-portal setup-link endpoints so a customer\u2019s IT admin self-serves their SSO/SCIM.",
1187
+ configKey: "portal",
1188
+ id: "portal",
1189
+ kind: "routes",
1190
+ label: "Admin portal"
1191
+ },
1192
+ {
1193
+ blurb: "Self-service session management: list the caller\u2019s active sessions and remote-revoke by id.",
1194
+ configKey: "sessions",
1195
+ id: "sessions",
1196
+ kind: "routes",
1197
+ label: "Session management"
1198
+ },
1199
+ {
1200
+ blurb: "GDPR/CCPA self-service: data export (right to access) + erasure (right to be forgotten).",
1201
+ configKey: "compliance",
1202
+ id: "compliance",
1203
+ kind: "routes",
1204
+ label: "Compliance"
1205
+ },
1206
+ {
1207
+ blurb: "Built-in HTMX fragment routes (login, identities, connectors, account, signout, delete-account).",
1208
+ configKey: "htmx",
1209
+ id: "htmx",
1210
+ kind: "routes",
1211
+ label: "HTMX fragments"
1212
+ },
1213
+ {
1214
+ blurb: "Append-only structured audit events (register, login, mfa_*, logout\u2026) to your store + hook. SOC 2 prerequisite.",
1215
+ configKey: "audit",
1216
+ id: "audit",
1217
+ kind: "behavior",
1218
+ label: "Audit log"
1219
+ },
1220
+ {
1221
+ blurb: "HMAC-signed outbound webhooks (Standard Webhooks) for every emitted auth event.",
1222
+ configKey: "webhooks",
1223
+ id: "webhooks",
1224
+ kind: "behavior",
1225
+ label: "Webhooks"
1226
+ },
1227
+ {
1228
+ blurb: "RBAC/ABAC: adds a protectPermission(check, handler) derive that delegates to your hasPermission hook.",
1229
+ configKey: "authorization",
1230
+ id: "authorization",
1231
+ kind: "behavior",
1232
+ label: "Authorization"
1233
+ },
1234
+ {
1235
+ blurb: "Per-identity attempt throttling + progressive account lockout on the credential login route.",
1236
+ configKey: "lockout",
1237
+ id: "lockout",
1238
+ kind: "behavior",
1239
+ label: "Lockout"
1240
+ }
1241
+ ];
1242
+ });
1243
+
1116
1244
  // node_modules/react-dom/cjs/react-dom.development.js
1117
1245
  var require_react_dom_development = __commonJS((exports) => {
1118
1246
  var React = __toESM(require_react());
@@ -31937,13 +32065,192 @@ var init_resolvePackageJson = __esm(() => {
31937
32065
  init_fromType();
31938
32066
  });
31939
32067
 
32068
+ // src/cli/config/auth/resolveAuthState.ts
32069
+ var exports_resolveAuthState = {};
32070
+ __export(exports_resolveAuthState, {
32071
+ resolveAuthState: () => resolveAuthState
32072
+ });
32073
+ import ts5 from "typescript";
32074
+ import { existsSync as existsSync10, readdirSync, readFileSync as readFileSync14 } from "fs";
32075
+ import { join as join2, relative, resolve as resolve9 } from "path";
32076
+ var AUTH_PACKAGE = "@absolutejs/auth", REPO_URL = "https://github.com/absolutejs/absolute-auth", NPM_URL = "https://www.npmjs.com/package/@absolutejs/auth", SKIP_DIRS, MAX_FILES = 4000, SETUP_EXPORTS, isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson = (path) => {
32077
+ if (!existsSync10(path))
32078
+ return null;
32079
+ try {
32080
+ const parsed = JSON.parse(readFileSync14(path, "utf-8"));
32081
+ return isRecord3(parsed) ? parsed : null;
32082
+ } catch {
32083
+ return null;
32084
+ }
32085
+ }, stringField = (record, key) => {
32086
+ const value = record?.[key];
32087
+ return typeof value === "string" ? value : null;
32088
+ }, declaredVersionFor = (cwd) => {
32089
+ const pkg = readJson(join2(cwd, "package.json"));
32090
+ if (!pkg)
32091
+ return null;
32092
+ for (const field of ["dependencies", "devDependencies"]) {
32093
+ const group = pkg[field];
32094
+ if (!isRecord3(group))
32095
+ continue;
32096
+ const version3 = group[AUTH_PACKAGE];
32097
+ if (typeof version3 === "string")
32098
+ return version3;
32099
+ }
32100
+ return null;
32101
+ }, installedVersionFor = (cwd) => stringField(readJson(join2(cwd, "node_modules", AUTH_PACKAGE, "package.json")), "version"), SOURCE_FILE, safeReaddir = (dir) => {
32102
+ try {
32103
+ return readdirSync(dir, { withFileTypes: true });
32104
+ } catch {
32105
+ return [];
32106
+ }
32107
+ }, sortEntry = (dir, entry, found, dirs) => {
32108
+ const full = join2(dir, entry.name);
32109
+ if (entry.isDirectory()) {
32110
+ if (SKIP_DIRS.has(entry.name) || entry.name.startsWith("."))
32111
+ return;
32112
+ dirs.push(full);
32113
+ return;
32114
+ }
32115
+ if (SOURCE_FILE.test(entry.name))
32116
+ found.push(full);
32117
+ }, collectFrom = (dir, found, stack) => {
32118
+ for (const entry of safeReaddir(dir))
32119
+ sortEntry(dir, entry, found, stack);
32120
+ }, candidateFiles = (root) => {
32121
+ const found = [];
32122
+ const stack = [root];
32123
+ while (stack.length > 0 && found.length < MAX_FILES) {
32124
+ const dir = stack.pop();
32125
+ if (dir === undefined)
32126
+ break;
32127
+ collectFrom(dir, found, stack);
32128
+ }
32129
+ return found;
32130
+ }, isAuthPackageImport = (statement) => ts5.isImportDeclaration(statement) && ts5.isStringLiteral(statement.moduleSpecifier) && statement.moduleSpecifier.text === AUTH_PACKAGE, addAuthNames = (statement, names) => {
32131
+ const bindings = statement.importClause?.namedBindings;
32132
+ if (!bindings || !ts5.isNamedImports(bindings))
32133
+ return;
32134
+ for (const element of bindings.elements) {
32135
+ const imported = element.propertyName?.text ?? element.name.text;
32136
+ if (!SETUP_EXPORTS.has(imported))
32137
+ continue;
32138
+ names.add(element.name.text);
32139
+ }
32140
+ }, authBindings = (sourceFile) => {
32141
+ const names = new Set;
32142
+ for (const statement of sourceFile.statements) {
32143
+ if (isAuthPackageImport(statement))
32144
+ addAuthNames(statement, names);
32145
+ }
32146
+ return names;
32147
+ }, isAuthCall = (node, bindings) => ts5.isIdentifier(node.expression) && bindings.has(node.expression.text), providerCountOf = (property) => {
32148
+ if (!ts5.isPropertyAssignment(property) || !ts5.isObjectLiteralExpression(property.initializer)) {
32149
+ return null;
32150
+ }
32151
+ return property.initializer.properties.length;
32152
+ }, readConfigKeys = (object) => {
32153
+ const keys = new Set;
32154
+ let providerCount = null;
32155
+ const usesSpread = object.properties.some((property) => ts5.isSpreadAssignment(property));
32156
+ for (const property of object.properties) {
32157
+ const { name } = property;
32158
+ if (name === undefined || !ts5.isIdentifier(name))
32159
+ continue;
32160
+ keys.add(name.text);
32161
+ if (name.text !== "providersConfiguration")
32162
+ continue;
32163
+ providerCount = providerCountOf(property);
32164
+ }
32165
+ return { keys, providerCount, usesSpread };
32166
+ }, matchFromCall = (node) => {
32167
+ const [arg] = node.arguments;
32168
+ if (arg && ts5.isObjectLiteralExpression(arg))
32169
+ return readConfigKeys(arg);
32170
+ return { keys: new Set, providerCount: null, usesSpread: true };
32171
+ }, readFileOrNull = (path) => {
32172
+ try {
32173
+ return readFileSync14(path, "utf-8");
32174
+ } catch {
32175
+ return null;
32176
+ }
32177
+ }, findSetupInFile = (path) => {
32178
+ const text = readFileOrNull(path);
32179
+ if (text === null || !text.includes(AUTH_PACKAGE))
32180
+ return null;
32181
+ const sourceFile = ts5.createSourceFile(path, text, ts5.ScriptTarget.Latest, true);
32182
+ const bindings = authBindings(sourceFile);
32183
+ if (bindings.size === 0)
32184
+ return null;
32185
+ let match = null;
32186
+ const visit2 = (node) => {
32187
+ if (match)
32188
+ return;
32189
+ if (ts5.isCallExpression(node) && isAuthCall(node, bindings)) {
32190
+ match = matchFromCall(node);
32191
+ return;
32192
+ }
32193
+ ts5.forEachChild(node, visit2);
32194
+ };
32195
+ visit2(sourceFile);
32196
+ return match;
32197
+ }, featureStatuses = (keys) => AUTH_FEATURES.map((feature) => ({
32198
+ blurb: feature.blurb,
32199
+ configKey: feature.configKey,
32200
+ configured: keys.has(feature.configKey),
32201
+ id: feature.id,
32202
+ kind: feature.kind,
32203
+ label: feature.label
32204
+ })), resolveAuthState = (cwd) => {
32205
+ const installedVersion = installedVersionFor(cwd);
32206
+ const root = existsSync10(join2(cwd, "src")) ? join2(cwd, "src") : cwd;
32207
+ let match = null;
32208
+ let setupPath = null;
32209
+ for (const file of candidateFiles(root)) {
32210
+ const found = findSetupInFile(file);
32211
+ if (found === null)
32212
+ continue;
32213
+ match = found;
32214
+ setupPath = relative(cwd, resolve9(file));
32215
+ break;
32216
+ }
32217
+ const keys = match?.keys ?? new Set;
32218
+ const state = {
32219
+ declaredVersion: declaredVersionFor(cwd),
32220
+ features: featureStatuses(keys),
32221
+ installed: installedVersion !== null,
32222
+ installedVersion,
32223
+ introspected: match !== null,
32224
+ npmUrl: NPM_URL,
32225
+ providerCount: match?.providerCount ?? null,
32226
+ repoUrl: REPO_URL,
32227
+ setupPath,
32228
+ usesSpread: match?.usesSpread ?? false
32229
+ };
32230
+ return state;
32231
+ };
32232
+ var init_resolveAuthState = __esm(() => {
32233
+ init_authCatalog();
32234
+ SKIP_DIRS = new Set([
32235
+ "node_modules",
32236
+ ".git",
32237
+ "build",
32238
+ "dist",
32239
+ ".absolutejs",
32240
+ "coverage",
32241
+ ".next"
32242
+ ]);
32243
+ SETUP_EXPORTS = new Set(["auth", "absoluteAuth"]);
32244
+ SOURCE_FILE = /\.(ts|tsx|mts|cts|js|mjs)$/;
32245
+ });
32246
+
31940
32247
  // src/cli/config/server.ts
31941
32248
  import { Elysia as Elysia2 } from "elysia";
31942
- import { existsSync as existsSync10, readFileSync as readFileSync14 } from "fs";
31943
- import { resolve as resolve9 } from "path";
32249
+ import { existsSync as existsSync11, readFileSync as readFileSync15 } from "fs";
32250
+ import { resolve as resolve10 } from "path";
31944
32251
 
31945
32252
  // src/cli/config/page/PanelHost.tsx
31946
- var import_react7 = __toESM(require_react(), 1);
32253
+ var import_react8 = __toESM(require_react(), 1);
31947
32254
 
31948
32255
  // src/cli/config/eslint/EslintPanel.tsx
31949
32256
  var import_react2 = __toESM(require_react(), 1);
@@ -34082,11 +34389,66 @@ var AbsoluteConfigPanel = ({
34082
34389
  }, undefined, true, undefined, this);
34083
34390
  };
34084
34391
 
34085
- // src/cli/config/packageJson/PackageJsonPanel.tsx
34392
+ // src/cli/config/integrations/IntegrationsPanel.tsx
34086
34393
  var import_react6 = __toESM(require_react(), 1);
34087
34394
  var jsx_dev_runtime6 = __toESM(require_jsx_dev_runtime(), 1);
34088
- var matchesQuery5 = (query, text) => query === "" || text.toLowerCase().includes(query.toLowerCase());
34089
- var FieldRow2 = ({ field, isSet, onSave, value }) => {
34395
+ var CONFIG_INTEGRATIONS = [
34396
+ { field: "openapi", title: "OpenAPI" },
34397
+ { field: "telemetry", title: "OpenTelemetry" }
34398
+ ];
34399
+ var MANUAL_PLUGINS = [
34400
+ {
34401
+ blurb: "Cross-origin resource sharing (CORS) headers.",
34402
+ id: "@elysiajs/cors",
34403
+ install: "bun add @elysiajs/cors",
34404
+ wire: ".use(cors())"
34405
+ },
34406
+ {
34407
+ blurb: "Sign and verify your own JWTs \u2014 custom API/service tokens.",
34408
+ id: "@elysiajs/jwt",
34409
+ install: "bun add @elysiajs/jwt",
34410
+ note: "Not for user login. For authentication (OAuth2, SSO, MFA, passkeys, sessions) use the Auth panel + @absolutejs/auth.",
34411
+ wire: ".use(jwt({ name: 'jwt', secret: getEnv('JWT_SECRET') }))"
34412
+ },
34413
+ {
34414
+ blurb: "Scheduled jobs on a cron pattern.",
34415
+ id: "@elysiajs/cron",
34416
+ install: "bun add @elysiajs/cron",
34417
+ wire: ".use(cron({ name: 'heartbeat', pattern: '0 */6 * * *', run() {} }))"
34418
+ }
34419
+ ];
34420
+ var ManualPluginCard = ({ blurb, id, install, note, wire }) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
34421
+ className: "rule",
34422
+ children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
34423
+ className: "rule-main",
34424
+ children: [
34425
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
34426
+ className: "rule-name-row",
34427
+ children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
34428
+ className: "rule-name",
34429
+ children: id
34430
+ }, undefined, false, undefined, this)
34431
+ }, undefined, false, undefined, this),
34432
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("p", {
34433
+ className: "rule-desc",
34434
+ children: blurb
34435
+ }, undefined, false, undefined, this),
34436
+ note && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("p", {
34437
+ className: "intg-note",
34438
+ children: note
34439
+ }, undefined, false, undefined, this),
34440
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("pre", {
34441
+ className: "intg-code",
34442
+ children: install
34443
+ }, undefined, false, undefined, this),
34444
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("pre", {
34445
+ className: "intg-code",
34446
+ children: wire
34447
+ }, undefined, false, undefined, this)
34448
+ ]
34449
+ }, undefined, true, undefined, this)
34450
+ }, undefined, false, undefined, this);
34451
+ var FieldRow2 = ({ busy, field, isSet, onSave, title, value }) => {
34090
34452
  const [draft, setDraft] = import_react6.useState(value);
34091
34453
  return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
34092
34454
  className: "rule fe-block",
@@ -34099,14 +34461,22 @@ var FieldRow2 = ({ field, isSet, onSave, value }) => {
34099
34461
  children: [
34100
34462
  /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
34101
34463
  className: "rule-name",
34464
+ children: title
34465
+ }, undefined, false, undefined, this),
34466
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
34467
+ className: "badge dep",
34102
34468
  children: field.name
34103
34469
  }, undefined, false, undefined, this),
34104
34470
  isSet && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
34105
34471
  className: "badge src",
34106
- children: "set"
34472
+ children: "on"
34107
34473
  }, undefined, false, undefined, this)
34108
34474
  ]
34109
34475
  }, undefined, true, undefined, this),
34476
+ field.description !== "" && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("p", {
34477
+ className: "rule-desc",
34478
+ children: field.description
34479
+ }, undefined, false, undefined, this),
34110
34480
  /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
34111
34481
  className: "fe-root",
34112
34482
  children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(FieldEditor, {
@@ -34122,11 +34492,503 @@ var FieldRow2 = ({ field, isSet, onSave, value }) => {
34122
34492
  children: [
34123
34493
  /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("button", {
34124
34494
  className: "ts-btn",
34495
+ disabled: busy,
34125
34496
  onClick: () => onSave(draft),
34126
34497
  type: "button",
34127
34498
  children: "save"
34128
34499
  }, undefined, false, undefined, this),
34129
34500
  isSet && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("button", {
34501
+ className: "ts-clear",
34502
+ onClick: () => onSave(undefined, true),
34503
+ type: "button",
34504
+ children: "disable"
34505
+ }, undefined, false, undefined, this)
34506
+ ]
34507
+ }, undefined, true, undefined, this)
34508
+ ]
34509
+ }, undefined, true, undefined, this);
34510
+ };
34511
+ var IntegrationsPanel = ({
34512
+ state: initial
34513
+ }) => {
34514
+ const [state, setState] = import_react6.useState(initial);
34515
+ const [busy, setBusy] = import_react6.useState(null);
34516
+ const [notice, setNotice] = import_react6.useState(null);
34517
+ const save = (name) => async (value, remove) => {
34518
+ setBusy(name);
34519
+ setNotice(null);
34520
+ try {
34521
+ const response = await fetch("/api/absolute", {
34522
+ body: JSON.stringify({ name, remove, value }),
34523
+ headers: { "Content-Type": "application/json" },
34524
+ method: "POST"
34525
+ });
34526
+ const result = await response.json();
34527
+ if (result.ok && result.state) {
34528
+ setState(result.state);
34529
+ setNotice({ kind: "ok", text: result.message });
34530
+ } else {
34531
+ setNotice({
34532
+ kind: "err",
34533
+ text: result.message ?? "Update failed"
34534
+ });
34535
+ }
34536
+ } catch (error) {
34537
+ setNotice({ kind: "err", text: String(error) });
34538
+ } finally {
34539
+ setBusy(null);
34540
+ }
34541
+ };
34542
+ const rows = CONFIG_INTEGRATIONS.map((entry) => ({
34543
+ field: state.fields.find((candidate) => candidate.name === entry.field),
34544
+ title: entry.title
34545
+ })).filter((row) => Boolean(row.field));
34546
+ return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
34547
+ className: "shell",
34548
+ children: [
34549
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("header", {
34550
+ className: "topbar",
34551
+ children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
34552
+ className: "brand",
34553
+ children: [
34554
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("h1", {
34555
+ className: "wordmark",
34556
+ children: [
34557
+ "integrations ",
34558
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("em", {
34559
+ children: "\xB7plugins"
34560
+ }, undefined, false, undefined, this)
34561
+ ]
34562
+ }, undefined, true, undefined, this),
34563
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
34564
+ className: "subpath",
34565
+ children: [
34566
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
34567
+ className: "dot"
34568
+ }, undefined, false, undefined, this),
34569
+ "official Elysia plugins, wired the AbsoluteJS way"
34570
+ ]
34571
+ }, undefined, true, undefined, this)
34572
+ ]
34573
+ }, undefined, true, undefined, this)
34574
+ }, undefined, false, undefined, this),
34575
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("main", {
34576
+ children: [
34577
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("section", {
34578
+ className: "section",
34579
+ children: [
34580
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
34581
+ className: "section-head",
34582
+ children: [
34583
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("h2", {
34584
+ className: "section-title",
34585
+ children: "Config-driven"
34586
+ }, undefined, false, undefined, this),
34587
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
34588
+ className: "section-files",
34589
+ children: "toggle in absolute.config.ts"
34590
+ }, undefined, false, undefined, this)
34591
+ ]
34592
+ }, undefined, true, undefined, this),
34593
+ rows.map((row) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(FieldRow2, {
34594
+ busy: busy === row.field.name,
34595
+ field: row.field,
34596
+ isSet: Object.prototype.hasOwnProperty.call(state.current, row.field.name),
34597
+ onSave: save(row.field.name),
34598
+ title: row.title,
34599
+ value: state.current[row.field.name]
34600
+ }, row.field.name, false, undefined, this))
34601
+ ]
34602
+ }, undefined, true, undefined, this),
34603
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("section", {
34604
+ className: "section",
34605
+ children: [
34606
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
34607
+ className: "section-head",
34608
+ children: [
34609
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("h2", {
34610
+ className: "section-title",
34611
+ children: "More official plugins"
34612
+ }, undefined, false, undefined, this),
34613
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
34614
+ className: "section-files",
34615
+ children: "install + wire"
34616
+ }, undefined, false, undefined, this)
34617
+ ]
34618
+ }, undefined, true, undefined, this),
34619
+ MANUAL_PLUGINS.map((plugin) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(ManualPluginCard, {
34620
+ ...plugin
34621
+ }, plugin.id, false, undefined, this))
34622
+ ]
34623
+ }, undefined, true, undefined, this)
34624
+ ]
34625
+ }, undefined, true, undefined, this),
34626
+ notice && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
34627
+ className: `toast ${notice.kind}`,
34628
+ children: [
34629
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("b", {
34630
+ children: notice.kind === "ok" ? "\u2713" : "\u2715"
34631
+ }, undefined, false, undefined, this),
34632
+ notice.text
34633
+ ]
34634
+ }, undefined, true, undefined, this)
34635
+ ]
34636
+ }, undefined, true, undefined, this);
34637
+ };
34638
+
34639
+ // src/cli/config/auth/AuthPanel.tsx
34640
+ init_authCatalog();
34641
+ var jsx_dev_runtime7 = __toESM(require_jsx_dev_runtime(), 1);
34642
+ var FeatureCard = ({ blurb, configKey, configured, kind, label }) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34643
+ className: "rule",
34644
+ children: /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34645
+ className: "rule-main",
34646
+ children: [
34647
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34648
+ className: "rule-name-row",
34649
+ children: [
34650
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
34651
+ className: "rule-name",
34652
+ children: label
34653
+ }, undefined, false, undefined, this),
34654
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
34655
+ className: "badge dep",
34656
+ children: configKey
34657
+ }, undefined, false, undefined, this),
34658
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
34659
+ className: "badge",
34660
+ children: kind
34661
+ }, undefined, false, undefined, this),
34662
+ configured && /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
34663
+ className: "badge src",
34664
+ children: "configured"
34665
+ }, undefined, false, undefined, this)
34666
+ ]
34667
+ }, undefined, true, undefined, this),
34668
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("p", {
34669
+ className: "rule-desc",
34670
+ children: blurb
34671
+ }, undefined, false, undefined, this)
34672
+ ]
34673
+ }, undefined, true, undefined, this)
34674
+ }, undefined, false, undefined, this);
34675
+ var NotInstalled = ({ npmUrl, repoUrl }) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34676
+ className: "shell",
34677
+ children: [
34678
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("header", {
34679
+ className: "topbar",
34680
+ children: /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34681
+ className: "brand",
34682
+ children: [
34683
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("h1", {
34684
+ className: "wordmark",
34685
+ children: [
34686
+ "auth ",
34687
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("em", {
34688
+ children: "\xB7@absolutejs/auth"
34689
+ }, undefined, false, undefined, this)
34690
+ ]
34691
+ }, undefined, true, undefined, this),
34692
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34693
+ className: "subpath",
34694
+ children: [
34695
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
34696
+ className: "dot"
34697
+ }, undefined, false, undefined, this),
34698
+ "not installed in this project"
34699
+ ]
34700
+ }, undefined, true, undefined, this)
34701
+ ]
34702
+ }, undefined, true, undefined, this)
34703
+ }, undefined, false, undefined, this),
34704
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("main", {
34705
+ children: /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("section", {
34706
+ className: "section",
34707
+ children: [
34708
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("p", {
34709
+ className: "rule-desc",
34710
+ children: "Enterprise auth for AbsoluteJS \u2014 OAuth2, credentials, SSO, SCIM, MFA, passkeys, organizations, and more. Install it, then this panel introspects your setup."
34711
+ }, undefined, false, undefined, this),
34712
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("pre", {
34713
+ className: "intg-code",
34714
+ children: "bun add @absolutejs/auth"
34715
+ }, undefined, false, undefined, this),
34716
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34717
+ className: "auth-links",
34718
+ children: [
34719
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("a", {
34720
+ className: "auth-link",
34721
+ href: repoUrl,
34722
+ rel: "noreferrer",
34723
+ target: "_blank",
34724
+ children: "GitHub \u2197"
34725
+ }, undefined, false, undefined, this),
34726
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("a", {
34727
+ className: "auth-link",
34728
+ href: npmUrl,
34729
+ rel: "noreferrer",
34730
+ target: "_blank",
34731
+ children: "npm \u2197"
34732
+ }, undefined, false, undefined, this)
34733
+ ]
34734
+ }, undefined, true, undefined, this)
34735
+ ]
34736
+ }, undefined, true, undefined, this)
34737
+ }, undefined, false, undefined, this)
34738
+ ]
34739
+ }, undefined, true, undefined, this);
34740
+ var AuthPanel = ({ state }) => {
34741
+ if (!state.installed)
34742
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(NotInstalled, {
34743
+ ...state
34744
+ }, undefined, false, undefined, this);
34745
+ const configuredCount = state.features.filter((feature) => feature.configured).length;
34746
+ const version = state.installedVersion ?? state.declaredVersion ?? "\u2014";
34747
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34748
+ className: "shell",
34749
+ children: [
34750
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("header", {
34751
+ className: "topbar",
34752
+ children: [
34753
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34754
+ className: "brand",
34755
+ children: [
34756
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("h1", {
34757
+ className: "wordmark",
34758
+ children: [
34759
+ "auth ",
34760
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("em", {
34761
+ children: "\xB7@absolutejs/auth"
34762
+ }, undefined, false, undefined, this)
34763
+ ]
34764
+ }, undefined, true, undefined, this),
34765
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34766
+ className: "subpath",
34767
+ children: [
34768
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
34769
+ className: "dot"
34770
+ }, undefined, false, undefined, this),
34771
+ state.setupPath ?? "no auth() call found"
34772
+ ]
34773
+ }, undefined, true, undefined, this)
34774
+ ]
34775
+ }, undefined, true, undefined, this),
34776
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34777
+ className: "counts",
34778
+ children: [
34779
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34780
+ className: "count",
34781
+ children: [
34782
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("b", {
34783
+ children: version
34784
+ }, undefined, false, undefined, this),
34785
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
34786
+ children: "version"
34787
+ }, undefined, false, undefined, this)
34788
+ ]
34789
+ }, undefined, true, undefined, this),
34790
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34791
+ className: "count",
34792
+ children: [
34793
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("b", {
34794
+ children: configuredCount
34795
+ }, undefined, false, undefined, this),
34796
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
34797
+ children: "features on"
34798
+ }, undefined, false, undefined, this)
34799
+ ]
34800
+ }, undefined, true, undefined, this)
34801
+ ]
34802
+ }, undefined, true, undefined, this)
34803
+ ]
34804
+ }, undefined, true, undefined, this),
34805
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("main", {
34806
+ children: [
34807
+ state.introspected ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34808
+ className: "auth-banner",
34809
+ children: [
34810
+ "Detected your ",
34811
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("code", {
34812
+ children: "auth()"
34813
+ }, undefined, false, undefined, this),
34814
+ " setup",
34815
+ state.setupPath ? ` in ${state.setupPath}` : "",
34816
+ state.providerCount === null ? "" : ` \xB7 ${state.providerCount} OAuth providers`,
34817
+ state.usesSpread ? " \xB7 config uses a spread, some keys may be hidden" : "",
34818
+ "."
34819
+ ]
34820
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34821
+ className: "auth-banner warn",
34822
+ children: [
34823
+ "Couldn\u2019t find an ",
34824
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("code", {
34825
+ children: "auth()"
34826
+ }, undefined, false, undefined, this),
34827
+ " call to introspect \u2014 showing the full capability catalog as a reference. Features are configured in code where you call ",
34828
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("code", {
34829
+ children: "auth()"
34830
+ }, undefined, false, undefined, this),
34831
+ "."
34832
+ ]
34833
+ }, undefined, true, undefined, this),
34834
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("section", {
34835
+ className: "section",
34836
+ children: [
34837
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34838
+ className: "section-head",
34839
+ children: [
34840
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("h2", {
34841
+ className: "section-title",
34842
+ children: "Core OAuth2 routes"
34843
+ }, undefined, false, undefined, this),
34844
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
34845
+ className: "section-files",
34846
+ children: "always mounted"
34847
+ }, undefined, false, undefined, this)
34848
+ ]
34849
+ }, undefined, true, undefined, this),
34850
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34851
+ className: "auth-chips",
34852
+ children: AUTH_CORE_ROUTES.map((route) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
34853
+ className: "auth-chip",
34854
+ children: route
34855
+ }, route, false, undefined, this))
34856
+ }, undefined, false, undefined, this)
34857
+ ]
34858
+ }, undefined, true, undefined, this),
34859
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("section", {
34860
+ className: "section",
34861
+ children: [
34862
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34863
+ className: "section-head",
34864
+ children: [
34865
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("h2", {
34866
+ className: "section-title",
34867
+ children: "Features"
34868
+ }, undefined, false, undefined, this),
34869
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
34870
+ className: "section-files",
34871
+ children: [
34872
+ configuredCount,
34873
+ " of ",
34874
+ state.features.length,
34875
+ " configured"
34876
+ ]
34877
+ }, undefined, true, undefined, this)
34878
+ ]
34879
+ }, undefined, true, undefined, this),
34880
+ state.features.map((feature) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(FeatureCard, {
34881
+ ...feature
34882
+ }, feature.id, false, undefined, this))
34883
+ ]
34884
+ }, undefined, true, undefined, this),
34885
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("section", {
34886
+ className: "section",
34887
+ children: [
34888
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34889
+ className: "section-head",
34890
+ children: /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("h2", {
34891
+ className: "section-title",
34892
+ children: "Related"
34893
+ }, undefined, false, undefined, this)
34894
+ }, undefined, false, undefined, this),
34895
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("p", {
34896
+ className: "rule-desc",
34897
+ children: [
34898
+ "Signing your own API/service tokens (not user login)? See",
34899
+ " ",
34900
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("code", {
34901
+ children: "@elysiajs/jwt"
34902
+ }, undefined, false, undefined, this),
34903
+ " in the",
34904
+ " ",
34905
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("a", {
34906
+ className: "auth-link",
34907
+ href: "/integrations",
34908
+ children: "Integrations panel"
34909
+ }, undefined, false, undefined, this),
34910
+ "."
34911
+ ]
34912
+ }, undefined, true, undefined, this),
34913
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34914
+ className: "auth-links",
34915
+ children: [
34916
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("a", {
34917
+ className: "auth-link",
34918
+ href: `${state.repoUrl}#features`,
34919
+ rel: "noreferrer",
34920
+ target: "_blank",
34921
+ children: "Features \u2197"
34922
+ }, undefined, false, undefined, this),
34923
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("a", {
34924
+ className: "auth-link",
34925
+ href: `${state.repoUrl}#configuration-options`,
34926
+ rel: "noreferrer",
34927
+ target: "_blank",
34928
+ children: "Configuration \u2197"
34929
+ }, undefined, false, undefined, this),
34930
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("a", {
34931
+ className: "auth-link",
34932
+ href: state.npmUrl,
34933
+ rel: "noreferrer",
34934
+ target: "_blank",
34935
+ children: "npm \u2197"
34936
+ }, undefined, false, undefined, this)
34937
+ ]
34938
+ }, undefined, true, undefined, this)
34939
+ ]
34940
+ }, undefined, true, undefined, this)
34941
+ ]
34942
+ }, undefined, true, undefined, this)
34943
+ ]
34944
+ }, undefined, true, undefined, this);
34945
+ };
34946
+
34947
+ // src/cli/config/packageJson/PackageJsonPanel.tsx
34948
+ var import_react7 = __toESM(require_react(), 1);
34949
+ var jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
34950
+ var matchesQuery5 = (query, text) => query === "" || text.toLowerCase().includes(query.toLowerCase());
34951
+ var FieldRow3 = ({ field, isSet, onSave, value }) => {
34952
+ const [draft, setDraft] = import_react7.useState(value);
34953
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34954
+ className: "rule fe-block",
34955
+ children: [
34956
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34957
+ className: "rule-main",
34958
+ children: [
34959
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34960
+ className: "rule-name-row",
34961
+ children: [
34962
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
34963
+ className: "rule-name",
34964
+ children: field.name
34965
+ }, undefined, false, undefined, this),
34966
+ isSet && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
34967
+ className: "badge src",
34968
+ children: "set"
34969
+ }, undefined, false, undefined, this)
34970
+ ]
34971
+ }, undefined, true, undefined, this),
34972
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34973
+ className: "fe-root",
34974
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(FieldEditor, {
34975
+ onChange: setDraft,
34976
+ schema: field.schema,
34977
+ value: draft
34978
+ }, undefined, false, undefined, this)
34979
+ }, undefined, false, undefined, this)
34980
+ ]
34981
+ }, undefined, true, undefined, this),
34982
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34983
+ className: "rule-controls fe-actions",
34984
+ children: [
34985
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("button", {
34986
+ className: "ts-btn",
34987
+ onClick: () => onSave(draft),
34988
+ type: "button",
34989
+ children: "save"
34990
+ }, undefined, false, undefined, this),
34991
+ isSet && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("button", {
34130
34992
  className: "ts-clear",
34131
34993
  onClick: () => onSave(undefined, true),
34132
34994
  type: "button",
@@ -34138,23 +35000,23 @@ var FieldRow2 = ({ field, isSet, onSave, value }) => {
34138
35000
  }, undefined, true, undefined, this);
34139
35001
  };
34140
35002
  var ScriptRow = ({ onRemove, onSave, script }) => {
34141
- const [draft, setDraft] = import_react6.useState(script.command);
34142
- return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35003
+ const [draft, setDraft] = import_react7.useState(script.command);
35004
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34143
35005
  className: "rule",
34144
- children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35006
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34145
35007
  className: "rule-main",
34146
35008
  children: [
34147
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35009
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34148
35010
  className: "rule-name-row",
34149
- children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
35011
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
34150
35012
  className: "rule-name",
34151
35013
  children: script.name
34152
35014
  }, undefined, false, undefined, this)
34153
35015
  }, undefined, false, undefined, this),
34154
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35016
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34155
35017
  className: "ts-control",
34156
35018
  children: [
34157
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("input", {
35019
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("input", {
34158
35020
  className: "ts-input wide",
34159
35021
  onChange: (event) => setDraft(event.target.value),
34160
35022
  onKeyDown: (event) => {
@@ -34164,13 +35026,13 @@ var ScriptRow = ({ onRemove, onSave, script }) => {
34164
35026
  spellCheck: false,
34165
35027
  value: draft
34166
35028
  }, undefined, false, undefined, this),
34167
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("button", {
35029
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("button", {
34168
35030
  className: "ts-btn",
34169
35031
  onClick: () => onSave(draft),
34170
35032
  type: "button",
34171
35033
  children: "save"
34172
35034
  }, undefined, false, undefined, this),
34173
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("button", {
35035
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("button", {
34174
35036
  className: "ts-clear",
34175
35037
  onClick: onRemove,
34176
35038
  type: "button",
@@ -34183,8 +35045,8 @@ var ScriptRow = ({ onRemove, onSave, script }) => {
34183
35045
  }, undefined, false, undefined, this);
34184
35046
  };
34185
35047
  var AddScript = ({ onAdd }) => {
34186
- const [name, setName] = import_react6.useState("");
34187
- const [command, setCommand] = import_react6.useState("");
35048
+ const [name, setName] = import_react7.useState("");
35049
+ const [command, setCommand] = import_react7.useState("");
34188
35050
  const add = () => {
34189
35051
  if (name.trim() === "")
34190
35052
  return;
@@ -34192,21 +35054,21 @@ var AddScript = ({ onAdd }) => {
34192
35054
  setName("");
34193
35055
  setCommand("");
34194
35056
  };
34195
- return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35057
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34196
35058
  className: "rule",
34197
- children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35059
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34198
35060
  className: "rule-main",
34199
- children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35061
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34200
35062
  className: "ts-control",
34201
35063
  children: [
34202
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("input", {
35064
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("input", {
34203
35065
  className: "ts-input",
34204
35066
  onChange: (event) => setName(event.target.value),
34205
35067
  placeholder: "script name",
34206
35068
  spellCheck: false,
34207
35069
  value: name
34208
35070
  }, undefined, false, undefined, this),
34209
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("input", {
35071
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("input", {
34210
35072
  className: "ts-input wide",
34211
35073
  onChange: (event) => setCommand(event.target.value),
34212
35074
  onKeyDown: (event) => {
@@ -34217,7 +35079,7 @@ var AddScript = ({ onAdd }) => {
34217
35079
  spellCheck: false,
34218
35080
  value: command
34219
35081
  }, undefined, false, undefined, this),
34220
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("button", {
35082
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("button", {
34221
35083
  className: "ts-btn",
34222
35084
  onClick: add,
34223
35085
  type: "button",
@@ -34229,9 +35091,9 @@ var AddScript = ({ onAdd }) => {
34229
35091
  }, undefined, false, undefined, this);
34230
35092
  };
34231
35093
  var PackageJsonPanel = ({ state: initial }) => {
34232
- const [state, setState] = import_react6.useState(initial);
34233
- const [query, setQuery] = import_react6.useState("");
34234
- const [notice, setNotice] = import_react6.useState(null);
35094
+ const [state, setState] = import_react7.useState(initial);
35095
+ const [query, setQuery] = import_react7.useState("");
35096
+ const [notice, setNotice] = import_react7.useState(null);
34235
35097
  const post = async (path, body) => {
34236
35098
  setNotice(null);
34237
35099
  try {
@@ -34257,28 +35119,28 @@ var PackageJsonPanel = ({ state: initial }) => {
34257
35119
  const saveField = (name) => (value, remove) => post("/api/package/field", { name, remove, value });
34258
35120
  const scripts = state.scripts.filter((script) => matchesQuery5(query, script.name) || matchesQuery5(query, script.command));
34259
35121
  const fields = state.fields.filter((field) => matchesQuery5(query, field.name));
34260
- return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35122
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34261
35123
  className: "shell",
34262
35124
  children: [
34263
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("header", {
35125
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("header", {
34264
35126
  className: "topbar",
34265
35127
  children: [
34266
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35128
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34267
35129
  className: "brand",
34268
35130
  children: [
34269
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("h1", {
35131
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("h1", {
34270
35132
  className: "wordmark",
34271
35133
  children: [
34272
35134
  "package ",
34273
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("em", {
35135
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("em", {
34274
35136
  children: ".json"
34275
35137
  }, undefined, false, undefined, this)
34276
35138
  ]
34277
35139
  }, undefined, true, undefined, this),
34278
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35140
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34279
35141
  className: "subpath",
34280
35142
  children: [
34281
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
35143
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
34282
35144
  className: "dot"
34283
35145
  }, undefined, false, undefined, this),
34284
35146
  state.configPath ?? "no package.json found"
@@ -34286,27 +35148,27 @@ var PackageJsonPanel = ({ state: initial }) => {
34286
35148
  }, undefined, true, undefined, this)
34287
35149
  ]
34288
35150
  }, undefined, true, undefined, this),
34289
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35151
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34290
35152
  className: "counts",
34291
35153
  children: [
34292
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35154
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34293
35155
  className: "count",
34294
35156
  children: [
34295
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("b", {
35157
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("b", {
34296
35158
  children: state.scripts.length
34297
35159
  }, undefined, false, undefined, this),
34298
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
35160
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
34299
35161
  children: "scripts"
34300
35162
  }, undefined, false, undefined, this)
34301
35163
  ]
34302
35164
  }, undefined, true, undefined, this),
34303
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35165
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34304
35166
  className: "count",
34305
35167
  children: [
34306
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("b", {
35168
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("b", {
34307
35169
  children: state.fields.length
34308
35170
  }, undefined, false, undefined, this),
34309
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
35171
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
34310
35172
  children: "fields"
34311
35173
  }, undefined, false, undefined, this)
34312
35174
  ]
@@ -34315,28 +35177,28 @@ var PackageJsonPanel = ({ state: initial }) => {
34315
35177
  }, undefined, true, undefined, this)
34316
35178
  ]
34317
35179
  }, undefined, true, undefined, this),
34318
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35180
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34319
35181
  className: "controls",
34320
- children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("input", {
35182
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("input", {
34321
35183
  className: "search",
34322
35184
  onChange: (event) => setQuery(event.target.value),
34323
35185
  placeholder: "Search scripts or fields\u2026",
34324
35186
  value: query
34325
35187
  }, undefined, false, undefined, this)
34326
35188
  }, undefined, false, undefined, this),
34327
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("main", {
35189
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("main", {
34328
35190
  children: [
34329
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("section", {
35191
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("section", {
34330
35192
  className: "section",
34331
35193
  children: [
34332
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35194
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34333
35195
  className: "section-head",
34334
35196
  children: [
34335
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("h2", {
35197
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("h2", {
34336
35198
  className: "section-title",
34337
35199
  children: "Scripts"
34338
35200
  }, undefined, false, undefined, this),
34339
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
35201
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
34340
35202
  className: "section-files",
34341
35203
  children: [
34342
35204
  state.scripts.length,
@@ -34345,7 +35207,7 @@ var PackageJsonPanel = ({ state: initial }) => {
34345
35207
  }, undefined, true, undefined, this)
34346
35208
  ]
34347
35209
  }, undefined, true, undefined, this),
34348
- scripts.map((script) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(ScriptRow, {
35210
+ scripts.map((script) => /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(ScriptRow, {
34349
35211
  onRemove: () => post("/api/package/script", {
34350
35212
  name: script.name,
34351
35213
  remove: true
@@ -34356,22 +35218,22 @@ var PackageJsonPanel = ({ state: initial }) => {
34356
35218
  }),
34357
35219
  script
34358
35220
  }, script.name, false, undefined, this)),
34359
- query === "" && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(AddScript, {
35221
+ query === "" && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(AddScript, {
34360
35222
  onAdd: (name, command) => post("/api/package/script", { command, name })
34361
35223
  }, undefined, false, undefined, this)
34362
35224
  ]
34363
35225
  }, undefined, true, undefined, this),
34364
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("section", {
35226
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("section", {
34365
35227
  className: "section",
34366
35228
  children: [
34367
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35229
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34368
35230
  className: "section-head",
34369
35231
  children: [
34370
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("h2", {
35232
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("h2", {
34371
35233
  className: "section-title",
34372
35234
  children: "Fields"
34373
35235
  }, undefined, false, undefined, this),
34374
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("span", {
35236
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
34375
35237
  className: "section-files",
34376
35238
  children: [
34377
35239
  state.fields.length,
@@ -34380,7 +35242,7 @@ var PackageJsonPanel = ({ state: initial }) => {
34380
35242
  }, undefined, true, undefined, this)
34381
35243
  ]
34382
35244
  }, undefined, true, undefined, this),
34383
- fields.map((field) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(FieldRow2, {
35245
+ fields.map((field) => /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(FieldRow3, {
34384
35246
  field,
34385
35247
  isSet: Object.prototype.hasOwnProperty.call(state.current, field.name),
34386
35248
  onSave: saveField(field.name),
@@ -34390,10 +35252,10 @@ var PackageJsonPanel = ({ state: initial }) => {
34390
35252
  }, undefined, true, undefined, this)
34391
35253
  ]
34392
35254
  }, undefined, true, undefined, this),
34393
- notice && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("div", {
35255
+ notice && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
34394
35256
  className: `toast ${notice.kind}`,
34395
35257
  children: [
34396
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("b", {
35258
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("b", {
34397
35259
  children: notice.kind === "ok" ? "\u2713" : "\u2715"
34398
35260
  }, undefined, false, undefined, this),
34399
35261
  notice.text
@@ -34404,38 +35266,42 @@ var PackageJsonPanel = ({ state: initial }) => {
34404
35266
  };
34405
35267
 
34406
35268
  // src/cli/config/page/PanelHost.tsx
34407
- var jsx_dev_runtime7 = __toESM(require_jsx_dev_runtime(), 1);
35269
+ var jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
34408
35270
  var ENDPOINTS = {
34409
35271
  absolute: "/api/absolute",
35272
+ auth: "/api/auth",
34410
35273
  eslint: "/api/rules",
35274
+ integrations: "/api/absolute",
34411
35275
  package: "/api/package",
34412
35276
  prettier: "/api/prettier",
34413
35277
  tsconfig: "/api/tsconfig"
34414
35278
  };
34415
35279
  var LABELS = {
34416
35280
  absolute: "absolute.config",
35281
+ auth: "Auth",
34417
35282
  eslint: "ESLint",
35283
+ integrations: "Integrations",
34418
35284
  package: "package.json",
34419
35285
  prettier: "Prettier",
34420
35286
  tsconfig: "tsconfig"
34421
35287
  };
34422
- var Message = ({ body, title }) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
35288
+ var Message = ({ body, title }) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV("div", {
34423
35289
  className: "cfg-placeholder",
34424
35290
  children: [
34425
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("h2", {
35291
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV("h2", {
34426
35292
  className: "cfg-placeholder-title",
34427
35293
  children: title
34428
35294
  }, undefined, false, undefined, this),
34429
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("p", {
35295
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV("p", {
34430
35296
  className: "cfg-placeholder-text",
34431
35297
  children: body
34432
35298
  }, undefined, false, undefined, this)
34433
35299
  ]
34434
35300
  }, undefined, true, undefined, this);
34435
- var Skeleton = ({ label }) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
35301
+ var Skeleton = ({ label }) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV("div", {
34436
35302
  className: "cfg-placeholder",
34437
35303
  children: [
34438
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("h2", {
35304
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV("h2", {
34439
35305
  className: "cfg-placeholder-title cfg-loading",
34440
35306
  children: [
34441
35307
  "Loading ",
@@ -34443,7 +35309,7 @@ var Skeleton = ({ label }) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
34443
35309
  "\u2026"
34444
35310
  ]
34445
35311
  }, undefined, true, undefined, this),
34446
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("p", {
35312
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV("p", {
34447
35313
  className: "cfg-placeholder-text",
34448
35314
  children: "Reading your configuration."
34449
35315
  }, undefined, false, undefined, this)
@@ -34453,44 +35319,61 @@ var isCatalog = (value) => isRecord(value) && Array.isArray(value.meta) && Array
34453
35319
  var isTsState = (value) => isRecord(value) && Array.isArray(value.options);
34454
35320
  var isPrettierState = (value) => isRecord(value) && Array.isArray(value.options);
34455
35321
  var isAbsoluteState = (value) => isRecord(value) && Array.isArray(value.fields);
35322
+ var isAuthState = (value) => isRecord(value) && Array.isArray(value.features);
34456
35323
  var isPackageState = (value) => isRecord(value) && Array.isArray(value.scripts) && Array.isArray(value.fields);
34457
35324
  var renderPanel = (panel, data) => {
34458
35325
  if (panel === "eslint") {
34459
- return isCatalog(data) && data.configPath ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(EslintPanel, {
35326
+ return isCatalog(data) && data.configPath ? /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(EslintPanel, {
34460
35327
  catalog: data
34461
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Message, {
35328
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Message, {
34462
35329
  body: "No flat ESLint config (eslint.config.{js,mjs,cjs,ts}) was found in this project.",
34463
35330
  title: "No ESLint config"
34464
35331
  }, undefined, false, undefined, this);
34465
35332
  }
34466
35333
  if (panel === "tsconfig") {
34467
- return isTsState(data) && data.configPath ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(TsconfigPanel, {
35334
+ return isTsState(data) && data.configPath ? /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(TsconfigPanel, {
34468
35335
  state: data
34469
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Message, {
35336
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Message, {
34470
35337
  body: "No tsconfig.json or jsconfig.json was found in this project.",
34471
35338
  title: "No tsconfig found"
34472
35339
  }, undefined, false, undefined, this);
34473
35340
  }
34474
35341
  if (panel === "prettier") {
34475
- return isPrettierState(data) && data.editable ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(PrettierPanel, {
35342
+ return isPrettierState(data) && data.editable ? /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(PrettierPanel, {
34476
35343
  state: data
34477
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Message, {
35344
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Message, {
34478
35345
  body: "Prettier isn't installed, or your config uses a JS/YAML format this editor can't rewrite. Switch to .prettierrc.json to edit it here.",
34479
35346
  title: "Prettier unavailable"
34480
35347
  }, undefined, false, undefined, this);
34481
35348
  }
34482
35349
  if (panel === "absolute") {
34483
- return isAbsoluteState(data) && data.configPath ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(AbsoluteConfigPanel, {
35350
+ return isAbsoluteState(data) && data.configPath ? /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(AbsoluteConfigPanel, {
35351
+ state: data
35352
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Message, {
35353
+ body: "No absolute.config.ts was found. Run with --config <path> to point at one.",
35354
+ title: "No absolute.config"
35355
+ }, undefined, false, undefined, this);
35356
+ }
35357
+ if (panel === "integrations") {
35358
+ return isAbsoluteState(data) && data.configPath ? /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(IntegrationsPanel, {
34484
35359
  state: data
34485
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Message, {
35360
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Message, {
34486
35361
  body: "No absolute.config.ts was found. Run with --config <path> to point at one.",
34487
35362
  title: "No absolute.config"
34488
35363
  }, undefined, false, undefined, this);
34489
35364
  }
35365
+ if (panel === "auth") {
35366
+ return isAuthState(data) ? /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(AuthPanel, {
35367
+ state: data
35368
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Message, {
35369
+ body: "Couldn't read the @absolutejs/auth setup for this project.",
35370
+ title: "Auth unavailable"
35371
+ }, undefined, false, undefined, this);
35372
+ }
34490
35373
  if (panel === "package") {
34491
- return isPackageState(data) && data.configPath ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(PackageJsonPanel, {
35374
+ return isPackageState(data) && data.configPath ? /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(PackageJsonPanel, {
34492
35375
  state: data
34493
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Message, {
35376
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Message, {
34494
35377
  body: "No package.json was found in this project.",
34495
35378
  title: "No package.json"
34496
35379
  }, undefined, false, undefined, this);
@@ -34498,9 +35381,9 @@ var renderPanel = (panel, data) => {
34498
35381
  return null;
34499
35382
  };
34500
35383
  var PanelHost = ({ panel }) => {
34501
- const [data, setData] = import_react7.useState(null);
34502
- const [phase, setPhase] = import_react7.useState("loading");
34503
- import_react7.useEffect(() => {
35384
+ const [data, setData] = import_react8.useState(null);
35385
+ const [phase, setPhase] = import_react8.useState("loading");
35386
+ import_react8.useEffect(() => {
34504
35387
  let active = true;
34505
35388
  setPhase("loading");
34506
35389
  fetch(ENDPOINTS[panel]).then((response) => response.json()).then((result) => {
@@ -34517,11 +35400,11 @@ var PanelHost = ({ panel }) => {
34517
35400
  };
34518
35401
  }, [panel]);
34519
35402
  if (phase === "loading")
34520
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Skeleton, {
35403
+ return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Skeleton, {
34521
35404
  label: LABELS[panel]
34522
35405
  }, undefined, false, undefined, this);
34523
35406
  if (phase === "error") {
34524
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Message, {
35407
+ return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Message, {
34525
35408
  body: "The config server didn't respond \u2014 check the terminal where it's running.",
34526
35409
  title: "Couldn't load"
34527
35410
  }, undefined, false, undefined, this);
@@ -35043,6 +35926,54 @@ var CONFIG_CSS = `
35043
35926
  .fe-raw { width: 100%; }
35044
35927
  .fe-raw .opts-input { width: 100%; }
35045
35928
 
35929
+ /* ---- integrations panel ---- */
35930
+ .intg-note {
35931
+ font-size: 11.5px;
35932
+ color: var(--warn);
35933
+ margin-top: 6px;
35934
+ max-width: 64ch;
35935
+ line-height: 1.45;
35936
+ }
35937
+ .intg-code {
35938
+ font-family: var(--mono);
35939
+ font-size: 11.5px;
35940
+ color: var(--accent-dim);
35941
+ background: var(--bg);
35942
+ border: 1px solid var(--border);
35943
+ border-radius: 7px;
35944
+ padding: 7px 10px;
35945
+ margin-top: 8px;
35946
+ overflow-x: auto;
35947
+ white-space: pre;
35948
+ }
35949
+
35950
+ /* ---- auth panel ---- */
35951
+ .auth-banner {
35952
+ font-size: 12px;
35953
+ color: var(--dim);
35954
+ background: var(--panel);
35955
+ border: 1px solid var(--border);
35956
+ border-radius: 9px;
35957
+ padding: 10px 14px;
35958
+ margin-bottom: 18px;
35959
+ line-height: 1.5;
35960
+ }
35961
+ .auth-banner.warn { color: var(--warn); border-color: rgba(240, 180, 41, 0.25); }
35962
+ .auth-banner code { color: var(--accent-dim); }
35963
+ .auth-chips { display: flex; flex-wrap: wrap; gap: 7px; }
35964
+ .auth-chip {
35965
+ font-family: var(--mono);
35966
+ font-size: 11px;
35967
+ color: var(--dim);
35968
+ background: var(--bg);
35969
+ border: 1px solid var(--border);
35970
+ border-radius: 7px;
35971
+ padding: 4px 9px;
35972
+ }
35973
+ .auth-links { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 10px; }
35974
+ .auth-link { font-size: 12px; color: var(--accent); text-decoration: none; }
35975
+ .auth-link:hover { text-decoration: underline; }
35976
+
35046
35977
  @media (max-width: 720px) {
35047
35978
  .cfg { flex-direction: column; }
35048
35979
  .cfg-nav {
@@ -35064,6 +35995,18 @@ var CONFIG_PANELS = [
35064
35995
  label: "absolute.config",
35065
35996
  status: "ready"
35066
35997
  },
35998
+ {
35999
+ blurb: "Official Elysia plugins",
36000
+ id: "integrations",
36001
+ label: "Integrations",
36002
+ status: "ready"
36003
+ },
36004
+ {
36005
+ blurb: "@absolutejs/auth setup",
36006
+ id: "auth",
36007
+ label: "Auth",
36008
+ status: "ready"
36009
+ },
35067
36010
  {
35068
36011
  blurb: "Scripts & metadata",
35069
36012
  id: "package",
@@ -35092,27 +36035,27 @@ var CONFIG_PANELS = [
35092
36035
  var DEFAULT_PANEL = "absolute";
35093
36036
 
35094
36037
  // src/cli/config/page/ConfigShell.tsx
35095
- var jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
35096
- var NavItem = ({ active, panel }) => /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("a", {
36038
+ var jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
36039
+ var NavItem = ({ active, panel }) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("a", {
35097
36040
  className: "cfg-item",
35098
36041
  "data-active": active,
35099
36042
  "data-soon": panel.status === "soon",
35100
36043
  href: `/${panel.id}`,
35101
36044
  children: [
35102
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
36045
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("span", {
35103
36046
  className: "cfg-item-top",
35104
36047
  children: [
35105
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
36048
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("span", {
35106
36049
  className: "cfg-item-name",
35107
36050
  children: panel.label
35108
36051
  }, undefined, false, undefined, this),
35109
- panel.status === "soon" && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
36052
+ panel.status === "soon" && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("span", {
35110
36053
  className: "cfg-soon",
35111
36054
  children: "soon"
35112
36055
  }, undefined, false, undefined, this)
35113
36056
  ]
35114
36057
  }, undefined, true, undefined, this),
35115
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
36058
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("span", {
35116
36059
  className: "cfg-item-blurb",
35117
36060
  children: panel.blurb
35118
36061
  }, undefined, false, undefined, this)
@@ -35121,74 +36064,74 @@ var NavItem = ({ active, panel }) => /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("a"
35121
36064
  var ConfigShell = ({ panel }) => {
35122
36065
  const active = CONFIG_PANELS.find((entry) => entry.id === panel);
35123
36066
  const activeLabel = active?.label ?? "Config";
35124
- return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("html", {
36067
+ return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("html", {
35125
36068
  lang: "en",
35126
36069
  children: [
35127
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("head", {
36070
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("head", {
35128
36071
  children: [
35129
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("meta", {
36072
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("meta", {
35130
36073
  charSet: "utf-8"
35131
36074
  }, undefined, false, undefined, this),
35132
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("meta", {
36075
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("meta", {
35133
36076
  content: "width=device-width, initial-scale=1",
35134
36077
  name: "viewport"
35135
36078
  }, undefined, false, undefined, this),
35136
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("title", {
36079
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("title", {
35137
36080
  children: `Absolute Config \xB7 ${activeLabel}`
35138
36081
  }, undefined, false, undefined, this),
35139
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("link", {
36082
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("link", {
35140
36083
  href: "https://fonts.googleapis.com",
35141
36084
  rel: "preconnect"
35142
36085
  }, undefined, false, undefined, this),
35143
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("link", {
36086
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("link", {
35144
36087
  crossOrigin: "anonymous",
35145
36088
  href: "https://fonts.gstatic.com",
35146
36089
  rel: "preconnect"
35147
36090
  }, undefined, false, undefined, this),
35148
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("link", {
36091
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("link", {
35149
36092
  href: "https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@400;500&display=swap",
35150
36093
  rel: "stylesheet"
35151
36094
  }, undefined, false, undefined, this),
35152
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("style", {
36095
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("style", {
35153
36096
  dangerouslySetInnerHTML: {
35154
36097
  __html: ESLINT_CSS + TSCONFIG_CSS + CONFIG_CSS
35155
36098
  }
35156
36099
  }, undefined, false, undefined, this)
35157
36100
  ]
35158
36101
  }, undefined, true, undefined, this),
35159
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("body", {
35160
- children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
36102
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("body", {
36103
+ children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
35161
36104
  className: "cfg",
35162
36105
  children: [
35163
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("aside", {
36106
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("aside", {
35164
36107
  className: "cfg-nav",
35165
36108
  children: [
35166
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
36109
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
35167
36110
  className: "cfg-brand",
35168
36111
  children: [
35169
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
36112
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("span", {
35170
36113
  className: "cfg-word",
35171
36114
  children: [
35172
36115
  "absolute ",
35173
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("em", {
36116
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("em", {
35174
36117
  children: "config"
35175
36118
  }, undefined, false, undefined, this)
35176
36119
  ]
35177
36120
  }, undefined, true, undefined, this),
35178
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
36121
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("span", {
35179
36122
  className: "cfg-tag",
35180
36123
  children: "project tooling"
35181
36124
  }, undefined, false, undefined, this)
35182
36125
  ]
35183
36126
  }, undefined, true, undefined, this),
35184
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("nav", {
36127
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("nav", {
35185
36128
  className: "cfg-panels",
35186
36129
  children: [
35187
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
36130
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
35188
36131
  className: "cfg-rail-label",
35189
36132
  children: "Panels"
35190
36133
  }, undefined, false, undefined, this),
35191
- CONFIG_PANELS.map((entry) => /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(NavItem, {
36134
+ CONFIG_PANELS.map((entry) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(NavItem, {
35192
36135
  active: entry.id === panel,
35193
36136
  panel: entry
35194
36137
  }, entry.id, false, undefined, this))
@@ -35196,9 +36139,9 @@ var ConfigShell = ({ panel }) => {
35196
36139
  }, undefined, true, undefined, this)
35197
36140
  ]
35198
36141
  }, undefined, true, undefined, this),
35199
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("main", {
36142
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("main", {
35200
36143
  className: "cfg-main",
35201
- children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(PanelHost, {
36144
+ children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(PanelHost, {
35202
36145
  panel
35203
36146
  }, undefined, false, undefined, this)
35204
36147
  }, undefined, false, undefined, this)
@@ -36817,14 +37760,15 @@ var packageOps = () => Promise.all([
36817
37760
  Promise.resolve().then(() => (init_editPackageJson(), exports_editPackageJson)),
36818
37761
  Promise.resolve().then(() => (init_resolvePackageJson(), exports_resolvePackageJson))
36819
37762
  ]);
37763
+ var authOps = () => Promise.resolve().then(() => (init_resolveAuthState(), exports_resolveAuthState));
36820
37764
  var CLIENT_ROUTE = "/config-client.js";
36821
37765
  var readVersion = () => {
36822
37766
  for (const candidate of [
36823
- resolve9(import.meta.dir, "..", "..", "..", "package.json"),
36824
- resolve9(import.meta.dir, "..", "..", "..", "..", "package.json")
37767
+ resolve10(import.meta.dir, "..", "..", "..", "package.json"),
37768
+ resolve10(import.meta.dir, "..", "..", "..", "..", "package.json")
36825
37769
  ]) {
36826
37770
  try {
36827
- const pkg = JSON.parse(readFileSync14(candidate, "utf-8"));
37771
+ const pkg = JSON.parse(readFileSync15(candidate, "utf-8"));
36828
37772
  if (typeof pkg?.version === "string")
36829
37773
  return pkg.version;
36830
37774
  } catch {}
@@ -36846,8 +37790,8 @@ var resolvePort = (args) => {
36846
37790
  };
36847
37791
  var resolveHost = (args) => flagValue(args, "--host") || process.env.ABSOLUTE_CONFIG_HOST || CONFIG_DEFAULT_HOST;
36848
37792
  var fileScopeOf = (query) => typeof query.file === "string" ? query.file : undefined;
36849
- var distClientBundle = resolve9(import.meta.dir, "client.js");
36850
- var sourceClientEntry = resolve9(import.meta.dir, "client.tsx");
37793
+ var distClientBundle = resolve10(import.meta.dir, "client.js");
37794
+ var sourceClientEntry = resolve10(import.meta.dir, "client.tsx");
36851
37795
  var cachedClientBundle = null;
36852
37796
  var buildClientBundle = async () => {
36853
37797
  const built = await Bun.build({
@@ -36868,7 +37812,7 @@ var buildClientBundle = async () => {
36868
37812
  var getClientBundle = async () => {
36869
37813
  if (cachedClientBundle !== null)
36870
37814
  return cachedClientBundle;
36871
- cachedClientBundle = existsSync10(distClientBundle) ? readFileSync14(distClientBundle, "utf-8") : await buildClientBundle();
37815
+ cachedClientBundle = existsSync11(distClientBundle) ? readFileSync15(distClientBundle, "utf-8") : await buildClientBundle();
36872
37816
  return cachedClientBundle;
36873
37817
  };
36874
37818
  var renderShell = (panel) => handleReactPageRequest({
@@ -37079,7 +38023,7 @@ var launchConfig = async (args, cwd = process.cwd()) => {
37079
38023
  const configOverride = flagValue(args, "--config");
37080
38024
  killStaleProcesses(port);
37081
38025
  const cert = httpsRequested ? ensureConfigCert(host) : null;
37082
- const app = new Elysia2().get("/", () => renderShell(DEFAULT_PANEL)).get("/eslint", () => renderShell("eslint")).get("/tsconfig", () => renderShell("tsconfig")).get("/prettier", () => renderShell("prettier")).get("/absolute", () => renderShell("absolute")).get("/package", () => renderShell("package")).get(CLIENT_ROUTE, async () => {
38026
+ const app = new Elysia2().get("/", () => renderShell(DEFAULT_PANEL)).get("/eslint", () => renderShell("eslint")).get("/tsconfig", () => renderShell("tsconfig")).get("/prettier", () => renderShell("prettier")).get("/absolute", () => renderShell("absolute")).get("/integrations", () => renderShell("integrations")).get("/auth", () => renderShell("auth")).get("/package", () => renderShell("package")).get(CLIENT_ROUTE, async () => {
37083
38027
  const bundle = await getClientBundle();
37084
38028
  return new Response(bundle, {
37085
38029
  headers: { "Content-Type": "text/javascript; charset=utf-8" }
@@ -37096,7 +38040,10 @@ var launchConfig = async (args, cwd = process.cwd()) => {
37096
38040
  }).post("/api/prettier", ({ body }) => handlePrettierEdit(cwd, body)).get("/api/absolute", async () => {
37097
38041
  const [, { resolveAbsoluteConfigState: resolveAbsoluteConfigState2 }] = await absoluteOps();
37098
38042
  return resolveAbsoluteConfigState2(cwd, configOverride);
37099
- }).post("/api/absolute", ({ body }) => handleAbsoluteEdit(cwd, body, configOverride)).get("/api/package", async () => {
38043
+ }).post("/api/absolute", ({ body }) => handleAbsoluteEdit(cwd, body, configOverride)).get("/api/auth", async () => {
38044
+ const { resolveAuthState: resolveAuthState2 } = await authOps();
38045
+ return resolveAuthState2(cwd);
38046
+ }).get("/api/package", async () => {
37100
38047
  const [, { resolvePackageJsonState: resolvePackageJsonState2 }] = await packageOps();
37101
38048
  return resolvePackageJsonState2(cwd);
37102
38049
  }).post("/api/package/script", ({ body }) => handleScriptEdit(cwd, body)).post("/api/package/field", ({ body }) => handleFieldEdit(cwd, body)).listen(listenOptions(port, cert));