webspresso 0.0.95 → 0.0.96
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/ADMIN.md +225 -0
- package/.agents/AGENTS.md +72 -0
- package/.agents/ARCHITECTURE.md +119 -0
- package/.agents/AUTH.md +103 -0
- package/.agents/CLI.md +115 -0
- package/.agents/COMPRESSION.md +59 -0
- package/.agents/CONVENTIONS.md +46 -0
- package/.agents/EMAIL.md +141 -0
- package/.agents/ERRORS.md +201 -0
- package/.agents/MCP.md +103 -0
- package/.agents/ORM.md +230 -0
- package/.agents/PLUGINS.md +419 -0
- package/.agents/QUEUE.md +113 -0
- package/.agents/REALTIME.md +213 -0
- package/.agents/ROUTING.md +292 -0
- package/.agents/SERVICES.md +341 -0
- package/.agents/SHUTDOWN.md +67 -0
- package/.agents/STREAMING.md +73 -0
- package/.agents/WORKFLOW.md +27 -0
- package/.agents/internal/DOCUMENTATION_REVIEW.md +485 -0
- package/.agents/internal/TECHNICAL_REVIEW.md +428 -0
- package/.cursorrules +14 -0
- package/AGENTS.md +175 -0
- package/CLAUDE.md +54 -0
- package/README.md +18 -14
- package/bin/commands/agents-init.js +169 -0
- package/bin/commands/api.js +114 -48
- package/bin/commands/doctor.js +35 -0
- package/bin/commands/new.js +13 -2
- package/bin/commands/page.js +75 -89
- package/bin/commands/service.js +77 -0
- package/bin/webspresso.js +2 -2
- package/core/compileSchema.js +1 -1
- package/core/errors/middleware.js +22 -2
- package/core/errors/normalize.js +29 -2
- package/{utils/schemaCache.js → core/schema-cache.js} +2 -3
- package/index.d.ts +306 -0
- package/index.js +35 -1
- package/package.json +5 -3
- package/plugins/admin-panel/client/parts/05-rich-text-file-helpers.js +22 -1
- package/plugins/csrf/index.js +3 -2
- package/plugins/csv/engine.js +447 -0
- package/plugins/csv/index.js +94 -0
- package/plugins/csv/middleware.js +80 -0
- package/plugins/csv/services.js +138 -0
- package/plugins/file-manager/admin-component.js +613 -0
- package/plugins/file-manager/api-handlers.js +261 -0
- package/plugins/file-manager/core.js +601 -0
- package/plugins/file-manager/index.js +139 -0
- package/plugins/file-manager/security.js +207 -0
- package/plugins/index.js +8 -0
- package/plugins/xlsx/engine.js +397 -0
- package/plugins/xlsx/index.js +91 -0
- package/plugins/xlsx/middleware.js +87 -0
- package/plugins/xlsx/services.js +118 -0
- package/src/api/api-loader.js +233 -0
- package/src/api/define-api.js +35 -0
- package/src/discovery/file-route-parser.js +201 -0
- package/src/discovery/scan-routes.js +265 -0
- package/src/file-router.js +6 -0
- package/src/modules/define-module.js +99 -0
- package/src/modules/module-discovery.js +117 -0
- package/src/pages/define-page.js +36 -0
- package/src/pages/page-loader.js +214 -0
- package/src/routing/mount-discovered-routes.js +78 -0
- package/src/routing/route-table.js +191 -0
- package/src/server.js +112 -15
- package/src/services/builtins/file-manager.js +178 -0
- package/src/services/index.js +2 -0
- package/bin/commands/skill.js +0 -187
- package/templates/skills/webspresso-usage/REFERENCE-framework.md +0 -289
- package/templates/skills/webspresso-usage/REFERENCE-kernel.md +0 -93
- package/templates/skills/webspresso-usage/SKILL.md +0 -48
package/index.d.ts
CHANGED
|
@@ -222,6 +222,11 @@ export function createMediaServices(options?: {
|
|
|
222
222
|
publicBasePath?: string;
|
|
223
223
|
}): Record<string, ServiceDefinition>;
|
|
224
224
|
|
|
225
|
+
export function createFileManagerServices(options?: {
|
|
226
|
+
baseDir?: string;
|
|
227
|
+
publicBasePath?: string;
|
|
228
|
+
}): Record<string, ServiceDefinition>;
|
|
229
|
+
|
|
225
230
|
export function createSystemServices(options?: {
|
|
226
231
|
db?: unknown;
|
|
227
232
|
serviceRegistry?: unknown;
|
|
@@ -706,6 +711,7 @@ export type Zdb = Record<string, any> & {
|
|
|
706
711
|
};
|
|
707
712
|
|
|
708
713
|
export const zdb: Zdb;
|
|
714
|
+
export const z: typeof import('zod').z;
|
|
709
715
|
|
|
710
716
|
export function createSchemaHelpers(z: typeof import('zod').z): Zdb;
|
|
711
717
|
|
|
@@ -1677,4 +1683,304 @@ export class McpServer {
|
|
|
1677
1683
|
export function mcpPlugin(options?: McpPluginOptions): WebspressoPlugin;
|
|
1678
1684
|
export function createMcpServer(options?: McpPluginOptions): McpServer;
|
|
1679
1685
|
|
|
1686
|
+
// --- File Manager Plugin ---
|
|
1687
|
+
|
|
1688
|
+
export interface FileManagerPluginOptions {
|
|
1689
|
+
baseDir?: string;
|
|
1690
|
+
publicBasePath?: string;
|
|
1691
|
+
apiPrefix?: string;
|
|
1692
|
+
pageTitle?: string;
|
|
1693
|
+
menuLabel?: string;
|
|
1694
|
+
menuOrder?: number;
|
|
1695
|
+
maxUploadBytes?: number;
|
|
1696
|
+
allowedExtensions?: string[] | null;
|
|
1697
|
+
allowedMimeTypes?: string[] | null;
|
|
1698
|
+
includePage?: boolean;
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
export function fileManagerPlugin(options?: FileManagerPluginOptions): WebspressoPlugin;
|
|
1702
|
+
|
|
1703
|
+
// --- XLSX Plugin & Toolkit ---
|
|
1704
|
+
|
|
1705
|
+
export interface XlsxColumn {
|
|
1706
|
+
header?: string;
|
|
1707
|
+
key: string;
|
|
1708
|
+
width?: number;
|
|
1709
|
+
style?: Record<string, unknown>;
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1712
|
+
export interface XlsxHeaderStyle {
|
|
1713
|
+
fill?: string;
|
|
1714
|
+
bg?: string;
|
|
1715
|
+
color?: string;
|
|
1716
|
+
textColor?: string;
|
|
1717
|
+
fontName?: string;
|
|
1718
|
+
fontSize?: number;
|
|
1719
|
+
bold?: boolean;
|
|
1720
|
+
align?: 'left' | 'center' | 'right';
|
|
1721
|
+
height?: number;
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
export interface XlsxSheetConfig {
|
|
1725
|
+
name?: string;
|
|
1726
|
+
columns?: XlsxColumn[];
|
|
1727
|
+
rows?: Record<string, unknown>[];
|
|
1728
|
+
data?: Record<string, unknown>[];
|
|
1729
|
+
autoWidth?: boolean;
|
|
1730
|
+
striped?: boolean;
|
|
1731
|
+
headerStyle?: XlsxHeaderStyle;
|
|
1732
|
+
views?: Array<Record<string, unknown>>;
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
export interface XlsxGenerateOptions {
|
|
1736
|
+
creator?: string;
|
|
1737
|
+
title?: string;
|
|
1738
|
+
created?: Date;
|
|
1739
|
+
sanitizeFormulas?: boolean;
|
|
1740
|
+
headerStyle?: XlsxHeaderStyle;
|
|
1741
|
+
sheets?: XlsxSheetConfig[] | XlsxSheetConfig;
|
|
1742
|
+
name?: string;
|
|
1743
|
+
columns?: XlsxColumn[];
|
|
1744
|
+
rows?: Record<string, unknown>[];
|
|
1745
|
+
data?: Record<string, unknown>[];
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
export interface XlsxParseOptions {
|
|
1749
|
+
sheet?: string | number;
|
|
1750
|
+
headerRow?: number;
|
|
1751
|
+
dataStartRow?: number;
|
|
1752
|
+
raw?: boolean;
|
|
1753
|
+
transformRow?: (row: Record<string, unknown>, index: number) => Record<string, unknown>;
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
export interface XlsxModelExportOptions {
|
|
1757
|
+
sheetName?: string;
|
|
1758
|
+
name?: string;
|
|
1759
|
+
creator?: string;
|
|
1760
|
+
title?: string;
|
|
1761
|
+
columns?: XlsxColumn[];
|
|
1762
|
+
headerStyle?: XlsxHeaderStyle;
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
export interface XlsxPluginOptions {
|
|
1766
|
+
enabled?: boolean;
|
|
1767
|
+
sanitizeFormulas?: boolean;
|
|
1768
|
+
headerStyle?: XlsxHeaderStyle;
|
|
1769
|
+
db?: unknown;
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
export interface XlsxToolkit {
|
|
1773
|
+
MIME_TYPE: string;
|
|
1774
|
+
generate(options: XlsxGenerateOptions): Promise<Buffer>;
|
|
1775
|
+
parse(input: Buffer | import('stream').Readable, options?: XlsxParseOptions): Promise<Record<string, unknown>[] | Record<string, Record<string, unknown>[]>>;
|
|
1776
|
+
fromModel(repository: unknown, filterOrQuery?: unknown, options?: XlsxModelExportOptions): Promise<Buffer>;
|
|
1777
|
+
createStreamWriter(outputStream: import('stream').Writable, options?: Record<string, unknown>): unknown;
|
|
1778
|
+
sanitizeFormula(value: unknown): unknown;
|
|
1779
|
+
applyHeaderStyle(worksheet: unknown, style?: XlsxHeaderStyle): void;
|
|
1780
|
+
applyAutoWidths(worksheet: unknown, columns: XlsxColumn[], rows: Record<string, unknown>[]): void;
|
|
1781
|
+
hexToArgb(hex: string): string;
|
|
1782
|
+
createMiddleware(globalOptions?: XlsxPluginOptions): import('express').RequestHandler;
|
|
1783
|
+
createServices(options?: Record<string, unknown>): Record<string, unknown>;
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
export const xlsx: XlsxToolkit;
|
|
1787
|
+
export function xlsxPlugin(options?: XlsxPluginOptions): WebspressoPlugin;
|
|
1788
|
+
|
|
1789
|
+
// --- CSV Plugin & Toolkit ---
|
|
1790
|
+
|
|
1791
|
+
export interface CsvColumn {
|
|
1792
|
+
header?: string;
|
|
1793
|
+
key: string;
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
export interface CsvGenerateOptions {
|
|
1797
|
+
rows?: Record<string, unknown>[];
|
|
1798
|
+
data?: Record<string, unknown>[];
|
|
1799
|
+
columns?: (CsvColumn | string)[];
|
|
1800
|
+
delimiter?: string;
|
|
1801
|
+
eol?: string;
|
|
1802
|
+
header?: boolean;
|
|
1803
|
+
bom?: boolean;
|
|
1804
|
+
sanitizeFormulas?: boolean;
|
|
1805
|
+
asBuffer?: boolean;
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
export interface CsvParseOptions {
|
|
1809
|
+
delimiter?: string;
|
|
1810
|
+
columns?: boolean | string[];
|
|
1811
|
+
skip_empty_lines?: boolean;
|
|
1812
|
+
trim?: boolean;
|
|
1813
|
+
relax_column_count?: boolean;
|
|
1814
|
+
transformRow?: (row: Record<string, unknown>, index: number) => Record<string, unknown>;
|
|
1815
|
+
[key: string]: unknown;
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
export interface CsvModelExportOptions {
|
|
1819
|
+
columns?: (CsvColumn | string)[];
|
|
1820
|
+
delimiter?: string;
|
|
1821
|
+
eol?: string;
|
|
1822
|
+
bom?: boolean;
|
|
1823
|
+
sanitizeFormulas?: boolean;
|
|
1824
|
+
asBuffer?: boolean;
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
export interface CsvPluginOptions {
|
|
1828
|
+
enabled?: boolean;
|
|
1829
|
+
delimiter?: string;
|
|
1830
|
+
bom?: boolean;
|
|
1831
|
+
sanitizeFormulas?: boolean;
|
|
1832
|
+
db?: unknown;
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
export interface CsvStreamWriter {
|
|
1836
|
+
writeHeader(columns?: (CsvColumn | string)[]): void;
|
|
1837
|
+
writeRow(row: Record<string, unknown>): void;
|
|
1838
|
+
writeRows(rows: Record<string, unknown>[]): void;
|
|
1839
|
+
end(): void;
|
|
1840
|
+
stream: import('stream').Writable;
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
export interface CsvToolkit {
|
|
1844
|
+
MIME_TYPE: string;
|
|
1845
|
+
UTF8_BOM: string;
|
|
1846
|
+
generate(options?: CsvGenerateOptions): Buffer | string;
|
|
1847
|
+
parse(input: Buffer | string | import('stream').Readable, options?: CsvParseOptions): Promise<Record<string, unknown>[]>;
|
|
1848
|
+
fromModel(repository: unknown, filterOrQuery?: unknown, options?: CsvModelExportOptions): Promise<Buffer>;
|
|
1849
|
+
createStreamWriter(outputStream: import('stream').Writable, options?: Record<string, unknown>): CsvStreamWriter;
|
|
1850
|
+
sanitizeFormula(value: unknown): unknown;
|
|
1851
|
+
escapeCsvField(value: unknown, options?: Record<string, unknown>): string;
|
|
1852
|
+
createMiddleware(globalOptions?: CsvPluginOptions): import('express').RequestHandler;
|
|
1853
|
+
createServices(options?: Record<string, unknown>): Record<string, unknown>;
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
export const csv: CsvToolkit;
|
|
1857
|
+
export function csvPlugin(options?: CsvPluginOptions): WebspressoPlugin;
|
|
1858
|
+
|
|
1859
|
+
// --- Discovery, Pages, API & Modules ---
|
|
1860
|
+
|
|
1861
|
+
export interface PageContext<TParams = Record<string, string>, TQuery = Record<string, string>> {
|
|
1862
|
+
req: import('express').Request;
|
|
1863
|
+
res: import('express').Response;
|
|
1864
|
+
params: TParams;
|
|
1865
|
+
query: TQuery;
|
|
1866
|
+
service: <TInput = unknown, TOutput = unknown>(name: string, input?: TInput, opts?: unknown) => Promise<TOutput>;
|
|
1867
|
+
module: string | null;
|
|
1868
|
+
config: Record<string, unknown>;
|
|
1869
|
+
logger: Console;
|
|
1870
|
+
redirect: (url: string, status?: number) => { __redirected: boolean };
|
|
1871
|
+
error: (status?: number, message?: string) => never;
|
|
1872
|
+
fsy: Record<string, unknown>;
|
|
1873
|
+
locale: string;
|
|
1874
|
+
t: (key: string, params?: Record<string, unknown>) => string;
|
|
1875
|
+
db: unknown;
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
export interface DefinePageOptions<TData = any, TParams = Record<string, string>, TQuery = Record<string, string>> {
|
|
1879
|
+
middleware?: (string | import('express').RequestHandler | [string, Record<string, unknown>])[];
|
|
1880
|
+
load?: (ctx: PageContext<TParams, TQuery>) => Promise<TData> | TData;
|
|
1881
|
+
head?: (data: TData, ctx: PageContext<TParams, TQuery>) => Record<string, unknown>;
|
|
1882
|
+
render?: (data: TData, ctx: PageContext<TParams, TQuery>) => string | Promise<string>;
|
|
1883
|
+
layout?: string | boolean;
|
|
1884
|
+
hooks?: Record<string, unknown>;
|
|
1885
|
+
meta?: Record<string, unknown>;
|
|
1886
|
+
[key: string]: unknown;
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
export function definePage<TData = any, TParams = Record<string, string>, TQuery = Record<string, string>>(
|
|
1890
|
+
config: DefinePageOptions<TData, TParams, TQuery> | ((ctx: PageContext<TParams, TQuery>) => Promise<TData> | TData)
|
|
1891
|
+
): DefinePageOptions<TData, TParams, TQuery>;
|
|
1892
|
+
|
|
1893
|
+
export interface ApiContext<TBody = any, TParams = Record<string, string>, TQuery = Record<string, string>> {
|
|
1894
|
+
req: import('express').Request;
|
|
1895
|
+
res: import('express').Response;
|
|
1896
|
+
params: TParams;
|
|
1897
|
+
query: TQuery;
|
|
1898
|
+
body: TBody;
|
|
1899
|
+
input: { body?: TBody; params?: TParams; query?: TQuery; headers?: Record<string, string> };
|
|
1900
|
+
service: <TInput = unknown, TOutput = unknown>(name: string, input?: TInput, opts?: unknown) => Promise<TOutput>;
|
|
1901
|
+
module: string | null;
|
|
1902
|
+
config: Record<string, unknown>;
|
|
1903
|
+
logger: Console;
|
|
1904
|
+
db: unknown;
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
export interface DefineApiOptions<TResult = any, TBody = any, TParams = Record<string, string>, TQuery = Record<string, string>> {
|
|
1908
|
+
description?: string;
|
|
1909
|
+
tags?: string[];
|
|
1910
|
+
middleware?: (string | import('express').RequestHandler | [string, Record<string, unknown>])[];
|
|
1911
|
+
schema?: {
|
|
1912
|
+
params?: unknown;
|
|
1913
|
+
query?: unknown;
|
|
1914
|
+
body?: unknown;
|
|
1915
|
+
headers?: unknown;
|
|
1916
|
+
} | ((helpers: { z: typeof import('zod').z }) => Record<string, unknown>);
|
|
1917
|
+
response?: Record<number | string, unknown>;
|
|
1918
|
+
handler: (req: import('express').Request, ctx: ApiContext<TBody, TParams, TQuery>) => Promise<TResult> | TResult;
|
|
1919
|
+
[key: string]: unknown;
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
export function defineApi<TResult = any, TBody = any, TParams = Record<string, string>, TQuery = Record<string, string>>(
|
|
1923
|
+
config: DefineApiOptions<TResult, TBody, TParams, TQuery> | ((req: import('express').Request, ctx: ApiContext<TBody, TParams, TQuery>) => Promise<TResult> | TResult)
|
|
1924
|
+
): DefineApiOptions<TResult, TBody, TParams, TQuery>;
|
|
1925
|
+
|
|
1926
|
+
export interface DefineModuleOptions {
|
|
1927
|
+
name: string;
|
|
1928
|
+
version?: string;
|
|
1929
|
+
description?: string;
|
|
1930
|
+
imports?: string[];
|
|
1931
|
+
dependencies?: string[];
|
|
1932
|
+
pages?: boolean | { dir?: string; prefix?: string };
|
|
1933
|
+
api?: boolean | { dir?: string; prefix?: string };
|
|
1934
|
+
services?: Record<string, unknown> | boolean | { dir?: string };
|
|
1935
|
+
middlewares?: Record<string, import('express').RequestHandler> | boolean | { dir?: string };
|
|
1936
|
+
exports?: Record<string, unknown>;
|
|
1937
|
+
apiExports?: Record<string, unknown>;
|
|
1938
|
+
onInit?: (ctx: unknown) => void | Promise<void>;
|
|
1939
|
+
onDestroy?: (ctx: unknown) => void | Promise<void>;
|
|
1940
|
+
[key: string]: unknown;
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1943
|
+
export function defineModule(config: DefineModuleOptions): (userOptions?: Record<string, unknown>) => WebspressoPlugin;
|
|
1944
|
+
|
|
1945
|
+
export interface RouteDescriptor {
|
|
1946
|
+
type: 'page' | 'api';
|
|
1947
|
+
method: string;
|
|
1948
|
+
path: string;
|
|
1949
|
+
file: string;
|
|
1950
|
+
source?: string;
|
|
1951
|
+
module?: string | null;
|
|
1952
|
+
description?: string;
|
|
1953
|
+
tags?: string[];
|
|
1954
|
+
moduleConfig?: unknown;
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
export class RouteTable {
|
|
1958
|
+
routes: ReadonlyArray<RouteDescriptor>;
|
|
1959
|
+
constructor(routes?: RouteDescriptor[]);
|
|
1960
|
+
list(): Array<{ method: string; path: string; type: string; module: string | null; source: string; description?: string; tags?: string[] }>;
|
|
1961
|
+
get(method: string, path: string): RouteDescriptor | undefined;
|
|
1962
|
+
has(method: string, path: string): boolean;
|
|
1963
|
+
get size(): number;
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
export function scanRoutes(options?: {
|
|
1967
|
+
rootDir?: string;
|
|
1968
|
+
pages?: boolean | { dir?: string; prefix?: string };
|
|
1969
|
+
api?: boolean | { dir?: string; prefix?: string };
|
|
1970
|
+
modules?: boolean | { dir?: string };
|
|
1971
|
+
}): RouteDescriptor[];
|
|
1972
|
+
|
|
1973
|
+
export function parseFileRoute(
|
|
1974
|
+
relativePath: string,
|
|
1975
|
+
options?: { type?: 'page' | 'api'; prefix?: string }
|
|
1976
|
+
): { path: string; method: string; isValid: boolean; isPrivate: boolean; originalMethodPart?: string };
|
|
1977
|
+
|
|
1978
|
+
export function compileRouteTable(
|
|
1979
|
+
descriptors?: RouteDescriptor[],
|
|
1980
|
+
options?: { explicitRoutes?: Array<{ method?: string; path: string }>; isDev?: boolean }
|
|
1981
|
+
): RouteTable;
|
|
1982
|
+
|
|
1983
|
+
|
|
1984
|
+
|
|
1985
|
+
|
|
1680
1986
|
|
package/index.js
CHANGED
|
@@ -52,6 +52,15 @@ const {
|
|
|
52
52
|
resetPluginManager
|
|
53
53
|
} = require('./src/plugin-manager');
|
|
54
54
|
|
|
55
|
+
// Discovery, Pages, API, Modules & Routing primitives
|
|
56
|
+
const { definePage } = require('./src/pages/define-page');
|
|
57
|
+
const { defineApi } = require('./src/api/define-api');
|
|
58
|
+
const { defineModule } = require('./src/modules/define-module');
|
|
59
|
+
const { scanRoutes } = require('./src/discovery/scan-routes');
|
|
60
|
+
const { parseFileRoute } = require('./src/discovery/file-route-parser');
|
|
61
|
+
const { compileRouteTable, RouteTable } = require('./src/routing/route-table');
|
|
62
|
+
const { mountDiscoveredRoutes } = require('./src/routing/mount-discovered-routes');
|
|
63
|
+
|
|
55
64
|
// ORM exports (lazy loaded)
|
|
56
65
|
const orm = require('./core/orm');
|
|
57
66
|
|
|
@@ -90,6 +99,11 @@ const {
|
|
|
90
99
|
mcpPlugin,
|
|
91
100
|
createMcpServer,
|
|
92
101
|
McpServer,
|
|
102
|
+
fileManagerPlugin,
|
|
103
|
+
xlsxPlugin,
|
|
104
|
+
xlsx,
|
|
105
|
+
csvPlugin,
|
|
106
|
+
csv,
|
|
93
107
|
} = require('./plugins');
|
|
94
108
|
|
|
95
109
|
const content = require('./core/content');
|
|
@@ -127,6 +141,7 @@ module.exports = {
|
|
|
127
141
|
createAuthServices: require('./src/services').createAuthServices,
|
|
128
142
|
createMailServices: require('./src/services').createMailServices,
|
|
129
143
|
createMediaServices: require('./src/services').createMediaServices,
|
|
144
|
+
createFileManagerServices: require('./src/services').createFileManagerServices,
|
|
130
145
|
createSystemServices: require('./src/services').createSystemServices,
|
|
131
146
|
createExchangeServices: require('./src/services').createExchangeServices,
|
|
132
147
|
validateServiceInput: require('./src/services').validateServiceInput,
|
|
@@ -205,8 +220,9 @@ module.exports = {
|
|
|
205
220
|
/** Event bus / plugin shell / view resolver / flows (`kernel.createApp` is distinct from SSR `createApp`) */
|
|
206
221
|
kernel,
|
|
207
222
|
|
|
208
|
-
// Direct zdb export (for convenience)
|
|
223
|
+
// Direct zdb & z export (for convenience)
|
|
209
224
|
zdb: orm.zdb,
|
|
225
|
+
z: require('./core/validation').z,
|
|
210
226
|
|
|
211
227
|
// Plugins
|
|
212
228
|
schemaExplorerPlugin,
|
|
@@ -243,6 +259,24 @@ module.exports = {
|
|
|
243
259
|
mcpPlugin,
|
|
244
260
|
createMcpServer,
|
|
245
261
|
McpServer,
|
|
262
|
+
fileManagerPlugin,
|
|
263
|
+
xlsxPlugin,
|
|
264
|
+
xlsx,
|
|
265
|
+
csvPlugin,
|
|
266
|
+
csv,
|
|
267
|
+
|
|
268
|
+
// Discovery, Pages, API, Modules & Routing primitives
|
|
269
|
+
definePage,
|
|
270
|
+
page: definePage,
|
|
271
|
+
defineApi,
|
|
272
|
+
api: defineApi,
|
|
273
|
+
defineModule,
|
|
274
|
+
module: defineModule,
|
|
275
|
+
scanRoutes,
|
|
276
|
+
parseFileRoute,
|
|
277
|
+
compileRouteTable,
|
|
278
|
+
RouteTable,
|
|
279
|
+
mountDiscoveredRoutes,
|
|
246
280
|
|
|
247
281
|
// Schema-driven CMS core (framework-agnostic)
|
|
248
282
|
content,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webspresso",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.96",
|
|
4
4
|
"description": "Minimal, production-ready SSR framework for Node.js with file-based routing, Nunjucks templating, built-in i18n, and CLI tooling",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -80,10 +80,12 @@
|
|
|
80
80
|
"index.d.ts",
|
|
81
81
|
"bin/",
|
|
82
82
|
"src/",
|
|
83
|
-
"utils/",
|
|
84
83
|
"core/",
|
|
85
84
|
"plugins/",
|
|
86
|
-
"
|
|
85
|
+
".agents/",
|
|
86
|
+
"AGENTS.md",
|
|
87
|
+
"CLAUDE.md",
|
|
88
|
+
".cursorrules",
|
|
87
89
|
"views/partials/webspresso-client-runtime.njk"
|
|
88
90
|
],
|
|
89
91
|
"dependencies": {
|
|
@@ -305,7 +305,28 @@ const FileUploadField = {
|
|
|
305
305
|
}),
|
|
306
306
|
m('div', [
|
|
307
307
|
m('p.text-gray-600.dark:text-slate-400.mb-2', displayUrl ? 'Drag and drop to replace, or' : 'Drag and drop a file here, or'),
|
|
308
|
-
m('
|
|
308
|
+
m('div.flex.items-center.justify-center.gap-3.flex-wrap', [
|
|
309
|
+
m('label.text-blue-600.hover:text-blue-800.dark:text-blue-400.cursor-pointer.font-medium', { for: 'file-input-' + col.name }, displayUrl ? 'choose another file' : 'browse'),
|
|
310
|
+
typeof window !== 'undefined' && window.__openFileManagerPicker
|
|
311
|
+
? m('button.text-indigo-600.hover:text-indigo-800.dark:text-indigo-400.cursor-pointer.font-medium.flex.items-center.gap-1', {
|
|
312
|
+
type: 'button',
|
|
313
|
+
onclick: function(e) {
|
|
314
|
+
e.preventDefault();
|
|
315
|
+
e.stopPropagation();
|
|
316
|
+
window.__openFileManagerPicker({
|
|
317
|
+
accept: accept,
|
|
318
|
+
title: '📁 Ortam Kütüphanesinden Seç',
|
|
319
|
+
onSelect: function(pickedUrl) {
|
|
320
|
+
if (onChange) onChange(pickedUrl);
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
}, [
|
|
325
|
+
m('span', '•'),
|
|
326
|
+
m('span', 'Kütüphaneden Seç')
|
|
327
|
+
])
|
|
328
|
+
: null
|
|
329
|
+
])
|
|
309
330
|
]),
|
|
310
331
|
]),
|
|
311
332
|
m('input[type=hidden]', { name: col.name, value: typeof value === 'string' ? value : '' }),
|
package/plugins/csrf/index.js
CHANGED
|
@@ -51,8 +51,9 @@ function isIgnored(req, ignorePaths) {
|
|
|
51
51
|
if (regex === undefined) {
|
|
52
52
|
const regexPattern = pattern
|
|
53
53
|
.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
54
|
-
.replace(/\*\*/g, '
|
|
55
|
-
.replace(/\*/g, '[^/]*')
|
|
54
|
+
.replace(/\*\*/g, '___GLOB_STAR_STAR___')
|
|
55
|
+
.replace(/\*/g, '[^/]*')
|
|
56
|
+
.replace(/___GLOB_STAR_STAR___/g, '.*');
|
|
56
57
|
regex = new RegExp(`^${regexPattern}$`);
|
|
57
58
|
if (ignoreRegexCache.size < 500) {
|
|
58
59
|
ignoreRegexCache.set(pattern, regex);
|