@absolutejs/absolute 0.19.0-beta.1014 → 0.19.0-beta.1016

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.
@@ -1,14 +1,14 @@
1
1
  import ts from 'typescript';
2
- export declare const findConfigPath: (cwd: string) => string | null;
2
+ export declare const findConfigPath: (cwd: string, override?: string) => string | null;
3
3
  export declare const findConfigObject: (sourceFile: ts.Node) => ts.ObjectLiteralExpression | null;
4
4
  export declare const parseConfigObject: (configPath: string) => {
5
5
  object: ts.ObjectLiteralExpression | null;
6
6
  text: string;
7
7
  };
8
- export declare const resolveAbsoluteConfigState: (cwd: string) => {
8
+ export declare const resolveAbsoluteConfigState: (cwd: string, override?: string) => {
9
9
  available: boolean;
10
- complexKeys: string[];
11
10
  configPath: string | null;
12
11
  current: Record<string, unknown>;
13
- fields: import("../../../../types/config").ConfigField[];
12
+ fields: import("../../../../types/config").FieldNode[];
13
+ opaqueKeys: string[];
14
14
  };
@@ -1,10 +1,9 @@
1
- import type { ConfigField } from '../../../../types/config';
1
+ import type { FieldNode } from '../../../../types/config';
2
2
  import type { PackageScript } from '../../../../types/packageJsonPanel';
3
3
  export declare const findPackageJsonPath: (cwd: string) => string | null;
4
4
  export declare const resolvePackageJsonState: (cwd: string) => {
5
- complexKeys: string[];
6
5
  configPath: string | null;
7
6
  current: Record<string, unknown>;
8
- fields: ConfigField[];
7
+ fields: FieldNode[];
9
8
  scripts: PackageScript[];
10
9
  };
@@ -1,16 +1,6 @@
1
1
  import type { ConfigPanelId } from '../../../../types/config';
2
- import type { RuleCatalog } from '../../../../types/eslintConfig';
3
- import type { TsConfigState } from '../../../../types/tsconfig';
4
- import type { PrettierState } from '../../../../types/prettier';
5
- import type { AbsoluteConfigState } from '../../../../types/absoluteConfig';
6
- import type { PackageJsonState } from '../../../../types/packageJsonPanel';
7
2
  type ConfigShellProps = {
8
- absoluteConfigState: AbsoluteConfigState | null;
9
- eslintCatalog: RuleCatalog | null;
10
- packageJsonState: PackageJsonState | null;
11
3
  panel: ConfigPanelId;
12
- prettierState: PrettierState | null;
13
- tsconfigState: TsConfigState | null;
14
4
  };
15
- export declare const ConfigShell: ({ absoluteConfigState, eslintCatalog, packageJsonState, panel, prettierState, tsconfigState }: ConfigShellProps) => import("react/jsx-runtime").JSX.Element;
5
+ export declare const ConfigShell: ({ panel }: ConfigShellProps) => import("react/jsx-runtime").JSX.Element;
16
6
  export {};
@@ -0,0 +1,9 @@
1
+ import type { FieldSchema } from '../../../../types/config';
2
+ type EditorProps = {
3
+ onChange: (value: unknown) => void;
4
+ schema: FieldSchema;
5
+ value: unknown;
6
+ };
7
+ export declare const emptyValue: (schema: FieldSchema) => unknown;
8
+ export declare const FieldEditor: (props: EditorProps) => import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { ConfigPanelId } from '../../../../types/config';
2
+ type PanelHostProps = {
3
+ panel: ConfigPanelId;
4
+ };
5
+ export declare const PanelHost: ({ panel }: PanelHostProps) => import("react/jsx-runtime").JSX.Element | null;
6
+ export {};
@@ -1 +1 @@
1
- export declare const CONFIG_CSS = "\n.cfg {\n\tposition: relative;\n\tz-index: 1;\n\tdisplay: flex;\n\talign-items: stretch;\n\tmin-height: 100vh;\n}\n\n.cfg-nav {\n\tflex: 0 0 240px;\n\twidth: 240px;\n\theight: 100vh;\n\tposition: sticky;\n\ttop: 0;\n\talign-self: flex-start;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 26px;\n\tpadding: 30px 18px;\n\tborder-right: 1px solid var(--border);\n\tbackground: rgba(17, 19, 23, 0.6);\n}\n\n.cfg-brand { display: flex; flex-direction: column; gap: 4px; }\n.cfg-word { font-family: var(--serif); font-size: 26px; line-height: 1; }\n.cfg-word em { color: var(--accent); font-style: italic; }\n.cfg-tag {\n\tcolor: var(--faint);\n\tfont-size: 10px;\n\ttext-transform: uppercase;\n\tletter-spacing: 1.5px;\n}\n\n.cfg-panels { display: flex; flex-direction: column; gap: 4px; }\n.cfg-rail-label {\n\tcolor: var(--faint);\n\tfont-size: 10px;\n\ttext-transform: uppercase;\n\tletter-spacing: 1.5px;\n\tpadding: 0 10px 8px;\n}\n\n.cfg-item {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tpadding: 10px 12px;\n\tborder-radius: 8px;\n\tborder: 1px solid transparent;\n\tcolor: var(--text);\n\ttext-decoration: none;\n\ttransition: background 0.12s ease, border-color 0.12s ease;\n}\n.cfg-item:hover { background: var(--panel-2); }\n.cfg-item[data-active='true'] { background: var(--panel-2); border-color: var(--border); }\n.cfg-item[data-soon='true'] { opacity: 0.6; }\n.cfg-item-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }\n.cfg-item-name { font-weight: 500; font-size: 13px; }\n.cfg-item-blurb { color: var(--dim); font-size: 11px; }\n.cfg-soon {\n\tfont-size: 9px;\n\ttext-transform: uppercase;\n\tletter-spacing: 1px;\n\tcolor: var(--bg);\n\tbackground: var(--accent-dim);\n\tpadding: 2px 6px;\n\tborder-radius: 999px;\n}\n\n.cfg-main { flex: 1 1 auto; min-width: 0; }\n\n.cfg-placeholder {\n\tposition: relative;\n\tz-index: 1;\n\tmax-width: 760px;\n\tmargin: 0 auto;\n\tpadding: 120px 28px;\n\ttext-align: center;\n}\n.cfg-placeholder-title { font-family: var(--serif); font-size: 40px; margin-bottom: 12px; }\n.cfg-placeholder-title em { color: var(--accent); font-style: italic; }\n.cfg-placeholder-text { color: var(--dim); font-size: 14px; max-width: 460px; margin: 0 auto; }\n\n@media (max-width: 720px) {\n\t.cfg { flex-direction: column; }\n\t.cfg-nav {\n\t\twidth: auto;\n\t\tflex-basis: auto;\n\t\theight: auto;\n\t\tposition: static;\n\t\tborder-right: none;\n\t\tborder-bottom: 1px solid var(--border);\n\t}\n}\n";
1
+ export declare const CONFIG_CSS = "\n.cfg {\n\tposition: relative;\n\tz-index: 1;\n\tdisplay: flex;\n\talign-items: stretch;\n\tmin-height: 100vh;\n}\n\n.cfg-nav {\n\tflex: 0 0 240px;\n\twidth: 240px;\n\theight: 100vh;\n\tposition: sticky;\n\ttop: 0;\n\talign-self: flex-start;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 26px;\n\tpadding: 30px 18px;\n\tborder-right: 1px solid var(--border);\n\tbackground: rgba(17, 19, 23, 0.6);\n}\n\n.cfg-brand { display: flex; flex-direction: column; gap: 4px; }\n.cfg-word { font-family: var(--serif); font-size: 26px; line-height: 1; }\n.cfg-word em { color: var(--accent); font-style: italic; }\n.cfg-tag {\n\tcolor: var(--faint);\n\tfont-size: 10px;\n\ttext-transform: uppercase;\n\tletter-spacing: 1.5px;\n}\n\n.cfg-panels { display: flex; flex-direction: column; gap: 4px; }\n.cfg-rail-label {\n\tcolor: var(--faint);\n\tfont-size: 10px;\n\ttext-transform: uppercase;\n\tletter-spacing: 1.5px;\n\tpadding: 0 10px 8px;\n}\n\n.cfg-item {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tpadding: 10px 12px;\n\tborder-radius: 8px;\n\tborder: 1px solid transparent;\n\tcolor: var(--text);\n\ttext-decoration: none;\n\ttransition: background 0.12s ease, border-color 0.12s ease;\n}\n.cfg-item:hover { background: var(--panel-2); }\n.cfg-item[data-active='true'] { background: var(--panel-2); border-color: var(--border); }\n.cfg-item[data-soon='true'] { opacity: 0.6; }\n.cfg-item-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }\n.cfg-item-name { font-weight: 500; font-size: 13px; }\n.cfg-item-blurb { color: var(--dim); font-size: 11px; }\n.cfg-soon {\n\tfont-size: 9px;\n\ttext-transform: uppercase;\n\tletter-spacing: 1px;\n\tcolor: var(--bg);\n\tbackground: var(--accent-dim);\n\tpadding: 2px 6px;\n\tborder-radius: 999px;\n}\n\n.cfg-main { flex: 1 1 auto; min-width: 0; }\n\n.cfg-placeholder {\n\tposition: relative;\n\tz-index: 1;\n\tmax-width: 760px;\n\tmargin: 0 auto;\n\tpadding: 120px 28px;\n\ttext-align: center;\n}\n.cfg-placeholder-title { font-family: var(--serif); font-size: 40px; margin-bottom: 12px; }\n.cfg-placeholder-title em { color: var(--accent); font-style: italic; }\n.cfg-placeholder-text { color: var(--dim); font-size: 14px; max-width: 460px; margin: 0 auto; }\n.cfg-loading { animation: cfg-pulse 1.2s ease-in-out infinite; }\n@keyframes cfg-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }\n\n/* ---- recursive field editor ---- */\n.fe-block { align-items: flex-start; }\n.fe-root { margin-top: 10px; width: 100%; }\n.fe-actions { flex-direction: column; gap: 6px; }\n.fe-object {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n\tborder-left: 2px solid var(--border);\n\tpadding-left: 14px;\n}\n.fe-field { display: flex; flex-direction: column; gap: 4px; }\n.fe-label { display: flex; align-items: center; gap: 8px; }\n.fe-name { color: var(--dim); font-size: 12px; }\n.fe-array, .fe-record, .fe-union { display: flex; flex-direction: column; gap: 6px; }\n.fe-item, .fe-entry { display: flex; align-items: flex-start; gap: 6px; }\n.fe-key { min-width: 160px; flex: 0 0 auto; }\n.fe-add {\n\talign-self: flex-start;\n\tfont-family: var(--mono);\n\tfont-size: 11px;\n\tcolor: var(--accent);\n\tbackground: transparent;\n\tborder: 1px dashed var(--border);\n\tborder-radius: 7px;\n\tpadding: 4px 10px;\n\tcursor: pointer;\n}\n.fe-add:hover { border-color: var(--accent); }\n.fe-remove {\n\tfont-family: var(--mono);\n\tfont-size: 11px;\n\tcolor: var(--dim);\n\tbackground: transparent;\n\tborder: 1px solid var(--border);\n\tborder-radius: 7px;\n\tpadding: 4px 8px;\n\tcursor: pointer;\n}\n.fe-remove:hover { color: var(--error); border-color: var(--error); }\n.fe-type { color: var(--faint); font-size: 11px; margin-top: 4px; }\n.fe-raw { width: 100%; }\n.fe-raw .opts-input { width: 100%; }\n\n@media (max-width: 720px) {\n\t.cfg { flex-direction: column; }\n\t.cfg-nav {\n\t\twidth: auto;\n\t\tflex-basis: auto;\n\t\theight: auto;\n\t\tposition: static;\n\t\tborder-right: none;\n\t\tborder-bottom: 1px solid var(--border);\n\t}\n}\n";
@@ -0,0 +1,3 @@
1
+ import type { FieldSchema } from '../../../../types/config';
2
+ export declare const fromJsonSchema: (schema: unknown, depth?: number) => FieldSchema;
3
+ export declare const eslintOptionsSchema: (metaSchema: unknown) => FieldSchema;
@@ -0,0 +1,2 @@
1
+ import type { FieldNode } from '../../../../types/config';
2
+ export declare const introspectType: (cwd: string, typeName: string, exclude?: Set<string>) => FieldNode[];
@@ -0,0 +1 @@
1
+ export declare const serializeValue: (value: unknown, level?: number, indent?: string) => string;
@@ -209,10 +209,10 @@ export declare const launchConfig: (args: string[], cwd?: string) => Promise<Ely
209
209
  response: {
210
210
  200: {
211
211
  available: boolean;
212
- complexKeys: string[];
213
212
  configPath: string | null;
214
213
  current: Record<string, unknown>;
215
- fields: import("../../../types/config").ConfigField[];
214
+ fields: import("../../../types/config").FieldNode[];
215
+ opaqueKeys: string[];
216
216
  };
217
217
  };
218
218
  };
@@ -242,10 +242,9 @@ export declare const launchConfig: (args: string[], cwd?: string) => Promise<Ely
242
242
  headers: unknown;
243
243
  response: {
244
244
  200: {
245
- complexKeys: string[];
246
245
  configPath: string | null;
247
246
  current: Record<string, unknown>;
248
- fields: import("../../../types/config").ConfigField[];
247
+ fields: import("../../../types/config").FieldNode[];
249
248
  scripts: import("../../../types/packageJsonPanel").PackageScript[];
250
249
  };
251
250
  };
@@ -287,7 +287,32 @@ export declare const prepare: (configOrPath?: string) => Promise<{
287
287
  response: {
288
288
  200: Response;
289
289
  };
290
- }, {} | {
290
+ }, {
291
+ ".absolutejs": {
292
+ "*": {
293
+ get: {
294
+ body: unknown;
295
+ params: {
296
+ "*": string;
297
+ } & {};
298
+ query: unknown;
299
+ headers: unknown;
300
+ response: {
301
+ 200: Bun.BunFile | "Not Found";
302
+ 422: {
303
+ type: "validation";
304
+ on: string;
305
+ summary?: string;
306
+ message?: string;
307
+ found?: unknown;
308
+ property?: string;
309
+ expected?: string;
310
+ };
311
+ };
312
+ };
313
+ };
314
+ };
315
+ } | ({
291
316
  [x: string]: {
292
317
  get: {
293
318
  body: unknown;
@@ -297,7 +322,32 @@ export declare const prepare: (configOrPath?: string) => Promise<{
297
322
  response: {};
298
323
  };
299
324
  };
300
- }, {
325
+ } & {
326
+ ".absolutejs": {
327
+ "*": {
328
+ get: {
329
+ body: unknown;
330
+ params: {
331
+ "*": string;
332
+ } & {};
333
+ query: unknown;
334
+ headers: unknown;
335
+ response: {
336
+ 200: Bun.BunFile | "Not Found";
337
+ 422: {
338
+ type: "validation";
339
+ on: string;
340
+ summary?: string;
341
+ message?: string;
342
+ found?: unknown;
343
+ property?: string;
344
+ expected?: string;
345
+ };
346
+ };
347
+ };
348
+ };
349
+ };
350
+ }), {
301
351
  derive: {};
302
352
  resolve: {};
303
353
  schema: {};
@@ -1,13 +1,14 @@
1
- import type { ConfigField } from './config';
1
+ import type { FieldNode } from './config';
2
2
  export type AbsoluteConfigState = {
3
3
  /** False when the BuildConfig type couldn't be resolved (catalog empty). */
4
4
  available: boolean;
5
5
  configPath: string | null;
6
- /** Simple top-level values literally present in defineConfig({...}). */
6
+ /** Values literally present in defineConfig({...}), read recursively. */
7
7
  current: Record<string, unknown>;
8
- /** Top-level keys present with a non-scalar (object/array/ref) value. */
9
- complexKeys: string[];
10
- fields: ConfigField[];
8
+ /** Top-level keys whose value contains code (refs/calls) — not form-editable. */
9
+ opaqueKeys: string[];
10
+ /** Recursive field catalog introspected from BaseBuildConfig. */
11
+ fields: FieldNode[];
11
12
  };
12
13
  export type AbsoluteConfigEditRequest = {
13
14
  name: string;
@@ -8,16 +8,43 @@ export type ConfigPanelMeta = {
8
8
  /** `'ready'` panels are interactive; `'soon'` panels render a placeholder. */
9
9
  status: ConfigPanelStatus;
10
10
  };
11
- export type ConfigFieldKind = 'string' | 'number' | 'boolean' | 'enum' | 'complex';
12
- /** A field recovered from a TypeScript type by introspection the shared unit
13
- * the absolute.config and package.json panels render. */
14
- export type ConfigField = {
15
- /** Allowed values for `enum` kinds; empty otherwise. */
16
- choices: string[];
11
+ /** A normalized, recursive description of a value's shape produced from a TS
12
+ * type (config panels) or a JSON Schema (ESLint rule options), and consumed by
13
+ * the recursive FieldEditor so every value gets a real UI instead of raw JSON.
14
+ * `opaque` is the last resort: a value we can't safely structure-edit (e.g. it
15
+ * references an imported binding); `typeText` is shown for it. */
16
+ export type FieldSchema = {
17
+ kind: 'string';
18
+ } | {
19
+ kind: 'number';
20
+ } | {
21
+ kind: 'boolean';
22
+ } | {
23
+ kind: 'enum';
24
+ choices: (string | number)[];
25
+ } | {
26
+ kind: 'array';
27
+ item: FieldSchema;
28
+ } | {
29
+ kind: 'tuple';
30
+ items: FieldSchema[];
31
+ } | {
32
+ kind: 'object';
33
+ fields: FieldNode[];
34
+ } | {
35
+ kind: 'record';
36
+ value: FieldSchema;
37
+ } | {
38
+ kind: 'union';
39
+ variants: FieldSchema[];
40
+ } | {
41
+ kind: 'opaque';
42
+ typeText: string;
43
+ };
44
+ /** A named field within an object schema (or a top-level config field). */
45
+ export type FieldNode = {
17
46
  description: string;
18
- kind: ConfigFieldKind;
19
47
  name: string;
20
48
  optional: boolean;
21
- /** The field's TypeScript type, shown for `complex` (read-only) fields. */
22
- typeText: string;
49
+ schema: FieldSchema;
23
50
  };
@@ -1,16 +1,14 @@
1
- import type { ConfigField } from './config';
1
+ import type { FieldNode } from './config';
2
2
  export type PackageScript = {
3
3
  command: string;
4
4
  name: string;
5
5
  };
6
6
  export type PackageJsonState = {
7
- /** Top-level keys present with a non-scalar (object/array) value. */
8
- complexKeys: string[];
9
7
  configPath: string | null;
10
- /** Scalar values literally present in the file, keyed by field name. */
8
+ /** Top-level values present in the file (excluding `scripts`). */
11
9
  current: Record<string, unknown>;
12
- /** Field catalog introspected from the PackageJson type (excludes scripts). */
13
- fields: ConfigField[];
10
+ /** Field catalog from the PackageJson type + any extra keys in the file. */
11
+ fields: FieldNode[];
14
12
  scripts: PackageScript[];
15
13
  };
16
14
  export type PackageScriptEdit = {
package/package.json CHANGED
@@ -343,7 +343,7 @@
343
343
  "bd": "bun run scripts/build.ts && bun",
344
344
  "build": "bun run scripts/build.ts",
345
345
  "build:native": "./native/build.sh",
346
- "config": "bun run src/cli/index.ts config",
346
+ "config:studio": "bun run src/cli/index.ts config --config example/absolute.config.ts",
347
347
  "db:push": "drizzle-kit push",
348
348
  "db:studio": "drizzle-kit studio",
349
349
  "dev": "TELEMETRY_OFF=1 bun run src/cli/index.ts dev example/server.ts --config example/absolute.config.ts",
@@ -400,5 +400,5 @@
400
400
  ]
401
401
  }
402
402
  },
403
- "version": "0.19.0-beta.1014"
403
+ "version": "0.19.0-beta.1016"
404
404
  }
@@ -1,2 +0,0 @@
1
- import type { ConfigField } from '../../../types/config';
2
- export declare const introspectType: (cwd: string, typeName: string, exclude?: Set<string>) => ConfigField[];