@openenvx/admin 0.1.0

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.
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Core types for @openenvx/admin
3
+ */
4
+ export type ComponentType<P = object> = (props: P) => unknown;
5
+ export interface ColumnSchema {
6
+ defaultValue?: unknown;
7
+ enumValues?: string[];
8
+ isForeignKey: boolean;
9
+ isPrimary: boolean;
10
+ maxLength?: number;
11
+ name: string;
12
+ nullable: boolean;
13
+ referencedTable?: string;
14
+ type: string;
15
+ }
16
+ export interface TableSchema {
17
+ columns: ColumnSchema[];
18
+ name: string;
19
+ primaryKey: string;
20
+ }
21
+ export interface AdminSchema {
22
+ tables: TableSchema[];
23
+ version: string;
24
+ }
25
+ export interface ListQuery {
26
+ filters?: Record<string, string>;
27
+ limit?: number;
28
+ order?: 'asc' | 'desc';
29
+ page?: number;
30
+ search?: string;
31
+ sort?: string;
32
+ }
33
+ export interface ListResult<T> {
34
+ data: T[];
35
+ limit: number;
36
+ page: number;
37
+ total: number;
38
+ totalPages: number;
39
+ }
40
+ export type PermissionCheck = (user: unknown, action: 'read' | 'create' | 'update' | 'delete', table: string) => Promise<boolean> | boolean;
41
+ export interface AdminRouterConfig {
42
+ databaseUrl: string;
43
+ permissions?: PermissionCheck;
44
+ schema: string;
45
+ }
46
+ export interface FieldConfig {
47
+ component?: ComponentType<FieldComponentProps>;
48
+ description?: string;
49
+ hidden?: boolean;
50
+ label?: string;
51
+ placeholder?: string;
52
+ validate?: (value: unknown) => boolean | string;
53
+ }
54
+ export interface FieldComponentProps {
55
+ disabled?: boolean;
56
+ error?: string;
57
+ name: string;
58
+ onChange: (value: unknown) => void;
59
+ schema: ColumnSchema;
60
+ value: unknown;
61
+ }
62
+ export interface TableConfig {
63
+ form?: {
64
+ layout?: FormLayout[];
65
+ fieldOverrides?: Record<string, FieldConfig>;
66
+ };
67
+ hidden?: boolean;
68
+ icon?: string;
69
+ label?: string;
70
+ list?: {
71
+ fields?: string[];
72
+ searchable?: string[];
73
+ defaultSort?: {
74
+ field: string;
75
+ direction: 'asc' | 'desc';
76
+ };
77
+ };
78
+ }
79
+ export interface FormLayout {
80
+ fields: string[];
81
+ section: string;
82
+ }
83
+ export interface AdminConfig {
84
+ appName?: string;
85
+ customPages?: CustomPage[];
86
+ tables?: Record<string, TableConfig>;
87
+ theme?: 'light' | 'dark' | 'system';
88
+ }
89
+ export interface CustomPage {
90
+ component: ComponentType;
91
+ label: string;
92
+ path: string;
93
+ }
94
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @openenvx/admin
3
+ *
4
+ * Zero-config admin panel for Drizzle ORM powered by Refine and shadcn/ui.
5
+ *
6
+ * @example
7
+ * Server setup:
8
+ * ```typescript
9
+ * import { createDrizzleDataProvider } from '@openenvx/admin/server';
10
+ * import { drizzle } from 'drizzle-orm/node-postgres';
11
+ * import * as schema from './db/schema';
12
+ *
13
+ * const db = drizzle(pool, { schema });
14
+ * export const dataProvider = createDrizzleDataProvider({
15
+ * db,
16
+ * resources: { users: 'users', posts: 'posts' }
17
+ * });
18
+ * ```
19
+ *
20
+ * Client setup:
21
+ * ```typescript
22
+ * import { createAdminResources } from '@openenvx/admin';
23
+ * import * as schema from './db/schema';
24
+ *
25
+ * const resources = createAdminResources({ schema });
26
+ * ```
27
+ */
28
+ export type { AdminResource, AdminResourcesConfig, } from './client/resources';
29
+ export { createAdminResources } from './client/resources';
30
+ export type { DrizzleDataProviderConfig } from './server/data-provider';
31
+ export { createDrizzleDataProvider } from './server/data-provider';
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,YAAY,EACV,aAAa,EACb,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,YAAY,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAExE,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,129 @@
1
+ //#region src/client/resources.ts
2
+ /**
3
+ * Generate Refine resources from Drizzle schema
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * import * as schema from './db/schema';
8
+ *
9
+ * const resources = createAdminResources({
10
+ * schema,
11
+ * exclude: ['migrations'],
12
+ * resources: {
13
+ * users: {
14
+ * label: 'Team Members',
15
+ * meta: { icon: 'Users' }
16
+ * }
17
+ * }
18
+ * });
19
+ * ```
20
+ */
21
+ function createAdminResources(config) {
22
+ const { schema, exclude = [], resources = {}, defaultIcon = "FileText" } = config;
23
+ const adminResources = [];
24
+ for (const [name, table] of Object.entries(schema)) {
25
+ if (exclude.includes(name) || isRelation(table)) continue;
26
+ if (!isTable(table)) continue;
27
+ const tableName = getTableName(table) || name;
28
+ const customConfig = resources[name] || {};
29
+ if (customConfig.hidden) continue;
30
+ const resource = {
31
+ name: tableName,
32
+ list: `/${tableName}`,
33
+ create: `/${tableName}/create`,
34
+ edit: `/${tableName}/edit/:id`,
35
+ show: `/${tableName}/show/:id`,
36
+ label: customConfig.label || capitalize(tableName),
37
+ icon: customConfig.icon || defaultIcon,
38
+ meta: {
39
+ label: customConfig.label || capitalize(tableName),
40
+ icon: customConfig.icon || defaultIcon,
41
+ ...customConfig.meta
42
+ },
43
+ ...customConfig
44
+ };
45
+ adminResources.push(resource);
46
+ }
47
+ return adminResources;
48
+ }
49
+ function isTable(value) {
50
+ if (typeof value !== "object" || value === null) return false;
51
+ const table = value;
52
+ return Symbol.for("drizzle:PgTable") in table || Symbol.for("drizzle:MySqlTable") in table || Symbol.for("drizzle:SQLiteTable") in table || typeof table[""] === "object" && table[""] !== null;
53
+ }
54
+ function isRelation(value) {
55
+ if (typeof value !== "object" || value === null) return false;
56
+ const rel = value;
57
+ return Symbol.for("drizzle:Relations") in rel || rel.config !== void 0 && typeof rel.config === "object";
58
+ }
59
+ function getTableName(table) {
60
+ if (typeof table !== "object" || table === null) return null;
61
+ const t = table;
62
+ const nameSymbol = Symbol.for("drizzle:Name");
63
+ if (nameSymbol in t) return t[nameSymbol];
64
+ if (typeof t[""] === "object" && t[""] !== null) {
65
+ const config = t[""];
66
+ const configNameSymbol = Symbol.for("drizzle:Name");
67
+ if (configNameSymbol in config) return config[configNameSymbol];
68
+ }
69
+ return null;
70
+ }
71
+ function capitalize(str) {
72
+ return str.charAt(0).toUpperCase() + str.slice(1);
73
+ }
74
+ //#endregion
75
+ //#region src/server/data-provider.ts
76
+ function createDrizzleDataProvider(config) {
77
+ const { db, resources } = config;
78
+ const getTableName = (resource) => {
79
+ return resources[resource] || resource;
80
+ };
81
+ return {
82
+ getList: async ({ resource, pagination }) => {
83
+ const tableName = getTableName(resource);
84
+ const table = db.query[tableName];
85
+ if (!table) throw new Error(`Table not found: ${tableName}`);
86
+ const page = pagination?.current || 1;
87
+ const pageSize = pagination?.pageSize || 10;
88
+ return {
89
+ data: await table.findMany({
90
+ limit: pageSize,
91
+ offset: (page - 1) * pageSize
92
+ }),
93
+ total: (await table.findMany()).length
94
+ };
95
+ },
96
+ getOne: async ({ resource, id }) => {
97
+ const tableName = getTableName(resource);
98
+ const table = db.query[tableName];
99
+ if (!table) throw new Error(`Table not found: ${tableName}`);
100
+ const result = await table.findFirst({ where: () => ({ id }) });
101
+ if (!result) throw new Error(`Record not found: ${id}`);
102
+ return { data: result };
103
+ },
104
+ create: async ({ resource, variables }) => {
105
+ const tableName = getTableName(resource);
106
+ const result = await db.insert(tableName).values(variables).returning();
107
+ return { data: Array.isArray(result) ? result[0] : result };
108
+ },
109
+ update: async ({ resource, id, variables }) => {
110
+ const tableName = getTableName(resource);
111
+ const result = await db.update(tableName).set(variables).where({ id }).returning();
112
+ return { data: Array.isArray(result) ? result[0] : result };
113
+ },
114
+ deleteOne: async ({ resource, id }) => {
115
+ const tableName = getTableName(resource);
116
+ await db.delete(tableName).where({ id });
117
+ return { data: { id } };
118
+ },
119
+ getApiUrl: () => "",
120
+ custom: async (_params) => {
121
+ await Promise.resolve(_params);
122
+ throw new Error("Custom method not implemented");
123
+ }
124
+ };
125
+ }
126
+ //#endregion
127
+ export { createAdminResources, createDrizzleDataProvider };
128
+
129
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/client/resources.ts","../src/server/data-provider.ts"],"sourcesContent":["/**\n * Generate Refine resources from Drizzle schema\n */\n\nimport type { ResourceProps } from '@refinedev/core';\n\nexport interface AdminResource extends ResourceProps {\n hidden?: boolean;\n icon?: string;\n label?: string;\n meta?: {\n label?: string;\n icon?: string;\n [key: string]: unknown;\n };\n}\n\nexport interface AdminResourcesConfig {\n /** Default icon for resources */\n defaultIcon?: string;\n /** Tables to exclude from the admin panel */\n exclude?: string[];\n /** Custom resource configurations */\n resources?: Record<string, Partial<AdminResource>>;\n /** Schema module exported from your Drizzle schema file */\n schema: Record<string, unknown>;\n}\n\n/**\n * Generate Refine resources from Drizzle schema\n *\n * @example\n * ```typescript\n * import * as schema from './db/schema';\n *\n * const resources = createAdminResources({\n * schema,\n * exclude: ['migrations'],\n * resources: {\n * users: {\n * label: 'Team Members',\n * meta: { icon: 'Users' }\n * }\n * }\n * });\n * ```\n */\nexport function createAdminResources(\n config: AdminResourcesConfig\n): AdminResource[] {\n const {\n schema,\n exclude = [],\n resources = {},\n defaultIcon = 'FileText',\n } = config;\n\n const adminResources: AdminResource[] = [];\n\n for (const [name, table] of Object.entries(schema)) {\n // Skip if it's a relation definition or excluded\n if (exclude.includes(name) || isRelation(table)) {\n continue;\n }\n\n // Check if it's a table (has the Drizzle table symbol)\n if (!isTable(table)) {\n continue;\n }\n\n // Get table name from the table object\n const tableName = getTableName(table) || name;\n\n // Get custom config for this resource\n const customConfig = resources[name] || {};\n\n // Skip if explicitly hidden\n if (customConfig.hidden) {\n continue;\n }\n\n const resource: AdminResource = {\n name: tableName,\n list: `/${tableName}`,\n create: `/${tableName}/create`,\n edit: `/${tableName}/edit/:id`,\n show: `/${tableName}/show/:id`,\n label: customConfig.label || capitalize(tableName),\n icon: customConfig.icon || defaultIcon,\n meta: {\n label: customConfig.label || capitalize(tableName),\n icon: customConfig.icon || defaultIcon,\n ...customConfig.meta,\n },\n ...customConfig,\n };\n\n adminResources.push(resource);\n }\n\n return adminResources;\n}\n\nfunction isTable(value: unknown): boolean {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const table = value as Record<string | symbol, unknown>;\n\n // Check for Drizzle table symbols\n return (\n Symbol.for('drizzle:PgTable') in table ||\n Symbol.for('drizzle:MySqlTable') in table ||\n Symbol.for('drizzle:SQLiteTable') in table ||\n // Fallback: check if it has table-specific properties\n (typeof table[''] === 'object' && table[''] !== null)\n );\n}\n\nfunction isRelation(value: unknown): boolean {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const rel = value as Record<string | symbol, unknown>;\n\n return (\n Symbol.for('drizzle:Relations') in rel ||\n (rel.config !== undefined && typeof rel.config === 'object')\n );\n}\n\nfunction getTableName(table: unknown): string | null {\n if (typeof table !== 'object' || table === null) {\n return null;\n }\n\n const t = table as Record<string | symbol, unknown>;\n\n // Try to get name from symbol\n const nameSymbol = Symbol.for('drizzle:Name');\n if (nameSymbol in t) {\n return t[nameSymbol] as string;\n }\n\n // Try to get from internal config\n if (typeof t[''] === 'object' && t[''] !== null) {\n const config = t[''] as Record<symbol, unknown>;\n const configNameSymbol = Symbol.for('drizzle:Name');\n if (configNameSymbol in config) {\n return config[configNameSymbol] as string;\n }\n }\n\n return null;\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n","/**\n * Refine Data Provider for Drizzle ORM\n * Implements the Refine DataProvider interface using Drizzle ORM\n */\n\nimport type {\n BaseRecord,\n CreateParams,\n CreateResponse,\n DataProvider,\n DeleteOneParams,\n DeleteOneResponse,\n GetListParams,\n GetListResponse,\n GetOneParams,\n GetOneResponse,\n UpdateParams,\n UpdateResponse,\n} from '@refinedev/core';\n\nexport interface DrizzleDataProviderConfig {\n /** Drizzle database instance with query capabilities */\n db: {\n query: Record<\n string,\n {\n findMany: (args?: Record<string, unknown>) => Promise<unknown[]>;\n findFirst: (args?: Record<string, unknown>) => Promise<unknown>;\n }\n >;\n insert: (table: string) => {\n values: (data: Record<string, unknown>) => {\n returning: () => Promise<unknown[]>;\n };\n };\n update: (table: string) => {\n set: (data: Record<string, unknown>) => {\n where: (condition: unknown) => { returning: () => Promise<unknown[]> };\n };\n };\n delete: (table: string) => {\n where: (condition: unknown) => Promise<unknown>;\n };\n };\n /** Table name mapping: resource name -> table name */\n resources: Record<string, string>;\n}\n\nexport function createDrizzleDataProvider(\n config: DrizzleDataProviderConfig\n): DataProvider {\n const { db, resources } = config;\n\n const getTableName = (resource: string): string => {\n return resources[resource] || resource;\n };\n\n const dataProvider: DataProvider = {\n getList: async <TData extends BaseRecord = BaseRecord>({\n resource,\n pagination,\n }: GetListParams): Promise<GetListResponse<TData>> => {\n const tableName = getTableName(resource);\n const table = db.query[tableName];\n\n if (!table) {\n throw new Error(`Table not found: ${tableName}`);\n }\n\n const page = pagination?.current || 1;\n const pageSize = pagination?.pageSize || 10;\n\n const result = await table.findMany({\n limit: pageSize,\n offset: (page - 1) * pageSize,\n });\n\n // Get total count by querying without limits\n const allResults = await table.findMany();\n\n return {\n data: result as TData[],\n total: allResults.length,\n };\n },\n\n getOne: async <TData extends BaseRecord = BaseRecord>({\n resource,\n id,\n }: GetOneParams): Promise<GetOneResponse<TData>> => {\n const tableName = getTableName(resource);\n const table = db.query[tableName];\n\n if (!table) {\n throw new Error(`Table not found: ${tableName}`);\n }\n\n const result = await table.findFirst({\n where: () => ({ id }),\n });\n\n if (!result) {\n throw new Error(`Record not found: ${id}`);\n }\n\n return {\n data: result as TData,\n };\n },\n\n create: async <\n TData extends BaseRecord = BaseRecord,\n TVariables = Record<string, unknown>,\n >({\n resource,\n variables,\n }: CreateParams<TVariables>): Promise<CreateResponse<TData>> => {\n const tableName = getTableName(resource);\n const result = await db\n .insert(tableName)\n .values(variables as Record<string, unknown>)\n .returning();\n\n return {\n data: (Array.isArray(result) ? result[0] : result) as TData,\n };\n },\n\n update: async <\n TData extends BaseRecord = BaseRecord,\n TVariables = Record<string, unknown>,\n >({\n resource,\n id,\n variables,\n }: UpdateParams<TVariables>): Promise<UpdateResponse<TData>> => {\n const tableName = getTableName(resource);\n const result = await db\n .update(tableName)\n .set(variables as Record<string, unknown>)\n .where({ id })\n .returning();\n\n return {\n data: (Array.isArray(result) ? result[0] : result) as TData,\n };\n },\n\n deleteOne: async <\n TData extends BaseRecord = BaseRecord,\n TVariables = Record<string, unknown>,\n >({\n resource,\n id,\n }: DeleteOneParams<TVariables>): Promise<DeleteOneResponse<TData>> => {\n const tableName = getTableName(resource);\n await db.delete(tableName).where({ id });\n\n return {\n data: { id } as TData,\n };\n },\n\n getApiUrl: () => '',\n\n custom: async <\n TData extends BaseRecord = BaseRecord,\n TQuery = unknown,\n TPayload = unknown,\n >(_params: {\n url: string;\n method: string;\n query?: TQuery;\n payload?: TPayload;\n }): Promise<{ data: TData }> => {\n await Promise.resolve(_params);\n throw new Error('Custom method not implemented');\n },\n };\n\n return dataProvider;\n}\n"],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Refine Data Provider for Drizzle ORM
3
+ * Implements the Refine DataProvider interface using Drizzle ORM
4
+ */
5
+ import type { DataProvider } from '@refinedev/core';
6
+ export interface DrizzleDataProviderConfig {
7
+ /** Drizzle database instance with query capabilities */
8
+ db: {
9
+ query: Record<string, {
10
+ findMany: (args?: Record<string, unknown>) => Promise<unknown[]>;
11
+ findFirst: (args?: Record<string, unknown>) => Promise<unknown>;
12
+ }>;
13
+ insert: (table: string) => {
14
+ values: (data: Record<string, unknown>) => {
15
+ returning: () => Promise<unknown[]>;
16
+ };
17
+ };
18
+ update: (table: string) => {
19
+ set: (data: Record<string, unknown>) => {
20
+ where: (condition: unknown) => {
21
+ returning: () => Promise<unknown[]>;
22
+ };
23
+ };
24
+ };
25
+ delete: (table: string) => {
26
+ where: (condition: unknown) => Promise<unknown>;
27
+ };
28
+ };
29
+ /** Table name mapping: resource name -> table name */
30
+ resources: Record<string, string>;
31
+ }
32
+ export declare function createDrizzleDataProvider(config: DrizzleDataProviderConfig): DataProvider;
33
+ //# sourceMappingURL=data-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-provider.d.ts","sourceRoot":"","sources":["../../src/server/data-provider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAIV,YAAY,EASb,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,yBAAyB;IACxC,wDAAwD;IACxD,EAAE,EAAE;QACF,KAAK,EAAE,MAAM,CACX,MAAM,EACN;YACE,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YACjE,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;SACjE,CACF,CAAC;QACF,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK;YACzB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK;gBACzC,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;aACrC,CAAC;SACH,CAAC;QACF,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK;YACzB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK;gBACtC,KAAK,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK;oBAAE,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;iBAAE,CAAC;aACxE,CAAC;SACH,CAAC;QACF,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK;YACzB,KAAK,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;SACjD,CAAC;KACH,CAAC;IACF,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,yBAAyB,GAChC,YAAY,CAmId"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Server-side exports for @openenvx/admin
3
+ */
4
+ export type { AdminRouterConfig } from '../core/types';
5
+ export type { DrizzleDataProviderConfig } from './data-provider';
6
+ export { createDrizzleDataProvider } from './data-provider';
7
+ export { createAdminRouter } from './router';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}