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.
Files changed (73) hide show
  1. package/.agents/ADMIN.md +225 -0
  2. package/.agents/AGENTS.md +72 -0
  3. package/.agents/ARCHITECTURE.md +119 -0
  4. package/.agents/AUTH.md +103 -0
  5. package/.agents/CLI.md +115 -0
  6. package/.agents/COMPRESSION.md +59 -0
  7. package/.agents/CONVENTIONS.md +46 -0
  8. package/.agents/EMAIL.md +141 -0
  9. package/.agents/ERRORS.md +201 -0
  10. package/.agents/MCP.md +103 -0
  11. package/.agents/ORM.md +230 -0
  12. package/.agents/PLUGINS.md +419 -0
  13. package/.agents/QUEUE.md +113 -0
  14. package/.agents/REALTIME.md +213 -0
  15. package/.agents/ROUTING.md +292 -0
  16. package/.agents/SERVICES.md +341 -0
  17. package/.agents/SHUTDOWN.md +67 -0
  18. package/.agents/STREAMING.md +73 -0
  19. package/.agents/WORKFLOW.md +27 -0
  20. package/.agents/internal/DOCUMENTATION_REVIEW.md +485 -0
  21. package/.agents/internal/TECHNICAL_REVIEW.md +428 -0
  22. package/.cursorrules +14 -0
  23. package/AGENTS.md +175 -0
  24. package/CLAUDE.md +54 -0
  25. package/README.md +18 -14
  26. package/bin/commands/agents-init.js +169 -0
  27. package/bin/commands/api.js +114 -48
  28. package/bin/commands/doctor.js +35 -0
  29. package/bin/commands/new.js +13 -2
  30. package/bin/commands/page.js +75 -89
  31. package/bin/commands/service.js +77 -0
  32. package/bin/webspresso.js +2 -2
  33. package/core/compileSchema.js +1 -1
  34. package/core/errors/middleware.js +22 -2
  35. package/core/errors/normalize.js +29 -2
  36. package/{utils/schemaCache.js → core/schema-cache.js} +2 -3
  37. package/index.d.ts +306 -0
  38. package/index.js +35 -1
  39. package/package.json +5 -3
  40. package/plugins/admin-panel/client/parts/05-rich-text-file-helpers.js +22 -1
  41. package/plugins/csrf/index.js +3 -2
  42. package/plugins/csv/engine.js +447 -0
  43. package/plugins/csv/index.js +94 -0
  44. package/plugins/csv/middleware.js +80 -0
  45. package/plugins/csv/services.js +138 -0
  46. package/plugins/file-manager/admin-component.js +613 -0
  47. package/plugins/file-manager/api-handlers.js +261 -0
  48. package/plugins/file-manager/core.js +601 -0
  49. package/plugins/file-manager/index.js +139 -0
  50. package/plugins/file-manager/security.js +207 -0
  51. package/plugins/index.js +8 -0
  52. package/plugins/xlsx/engine.js +397 -0
  53. package/plugins/xlsx/index.js +91 -0
  54. package/plugins/xlsx/middleware.js +87 -0
  55. package/plugins/xlsx/services.js +118 -0
  56. package/src/api/api-loader.js +233 -0
  57. package/src/api/define-api.js +35 -0
  58. package/src/discovery/file-route-parser.js +201 -0
  59. package/src/discovery/scan-routes.js +265 -0
  60. package/src/file-router.js +6 -0
  61. package/src/modules/define-module.js +99 -0
  62. package/src/modules/module-discovery.js +117 -0
  63. package/src/pages/define-page.js +36 -0
  64. package/src/pages/page-loader.js +214 -0
  65. package/src/routing/mount-discovered-routes.js +78 -0
  66. package/src/routing/route-table.js +191 -0
  67. package/src/server.js +112 -15
  68. package/src/services/builtins/file-manager.js +178 -0
  69. package/src/services/index.js +2 -0
  70. package/bin/commands/skill.js +0 -187
  71. package/templates/skills/webspresso-usage/REFERENCE-framework.md +0 -289
  72. package/templates/skills/webspresso-usage/REFERENCE-kernel.md +0 -93
  73. 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.95",
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
- "templates/",
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('label.text-blue-600.hover:text-blue-800.dark:text-blue-400.cursor-pointer', { for: 'file-input-' + col.name }, displayUrl ? 'choose another file' : 'browse'),
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 : '' }),
@@ -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);