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
@@ -0,0 +1,138 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Built-in CSV Services
5
+ * Exposed via ctx.service('csv.*') and req.service('csv.*')
6
+ * @module plugins/csv/services
7
+ */
8
+
9
+ const { z } = require('zod');
10
+ const { generate, parse, fromModel, CSV_MIME_TYPE } = require('./engine');
11
+
12
+ /**
13
+ * Creates built-in services for the CSV plugin
14
+ * @param {Object} [options]
15
+ * @param {Object} [options.db]
16
+ * @returns {Object.<string, Object>}
17
+ */
18
+ function createCsvServices(options = {}) {
19
+ return {
20
+ 'csv.generate': {
21
+ schema: z.object({
22
+ rows: z.array(z.record(z.any())).optional(),
23
+ data: z.array(z.record(z.any())).optional(),
24
+ columns: z
25
+ .array(
26
+ z.union([
27
+ z.string(),
28
+ z.object({
29
+ header: z.string().optional(),
30
+ key: z.string(),
31
+ }),
32
+ ])
33
+ )
34
+ .optional(),
35
+ delimiter: z.string().optional().default(','),
36
+ eol: z.string().optional().default('\r\n'),
37
+ header: z.boolean().optional().default(true),
38
+ bom: z.boolean().optional().default(true),
39
+ sanitizeFormulas: z.boolean().optional().default(true),
40
+ }),
41
+ handler: async (input) => {
42
+ const buffer = generate(input);
43
+ const csvString = buffer.toString('utf8');
44
+ return {
45
+ csv: csvString,
46
+ base64: buffer.toString('base64'),
47
+ size: buffer.length,
48
+ mimeType: CSV_MIME_TYPE,
49
+ };
50
+ },
51
+ },
52
+
53
+ 'csv.parse': {
54
+ schema: z.object({
55
+ text: z.string().optional(),
56
+ base64: z.string().optional(),
57
+ delimiter: z.string().optional(),
58
+ columns: z.union([z.boolean(), z.array(z.string())]).optional().default(true),
59
+ skip_empty_lines: z.boolean().optional().default(true),
60
+ trim: z.boolean().optional().default(true),
61
+ }),
62
+ handler: async (input) => {
63
+ let target;
64
+ if (input.text !== undefined) {
65
+ target = input.text;
66
+ } else if (input.base64) {
67
+ target = Buffer.from(input.base64, 'base64');
68
+ } else if (input.buffer) {
69
+ target = input.buffer;
70
+ } else {
71
+ throw new Error('csv.parse requires text, base64, or buffer');
72
+ }
73
+
74
+ const data = await parse(target, {
75
+ delimiter: input.delimiter,
76
+ columns: input.columns,
77
+ skip_empty_lines: input.skip_empty_lines,
78
+ trim: input.trim,
79
+ });
80
+
81
+ return {
82
+ data,
83
+ rowCount: data.length,
84
+ };
85
+ },
86
+ },
87
+
88
+ 'csv.exportModel': {
89
+ schema: z.object({
90
+ model: z.string().min(1),
91
+ filter: z.record(z.any()).optional().default({}),
92
+ columns: z.array(z.string()).optional(),
93
+ filename: z.string().optional(),
94
+ delimiter: z.string().optional().default(','),
95
+ bom: z.boolean().optional().default(true),
96
+ }),
97
+ handler: async (input, ctx) => {
98
+ const db = ctx.db || options.db;
99
+ if (!db || typeof db.getRepository !== 'function') {
100
+ throw new Error('csv.exportModel requires an active database connection');
101
+ }
102
+
103
+ const repo = db.getRepository(input.model);
104
+ if (!repo) {
105
+ throw new Error(`Model repository "${input.model}" not found`);
106
+ }
107
+
108
+ let customColumns;
109
+ if (input.columns) {
110
+ customColumns = input.columns.map((c) => ({
111
+ header: c,
112
+ key: c,
113
+ }));
114
+ }
115
+
116
+ const buffer = await fromModel(repo, input.filter, {
117
+ columns: customColumns,
118
+ delimiter: input.delimiter,
119
+ bom: input.bom,
120
+ });
121
+
122
+ const filename = input.filename || `${input.model.toLowerCase()}_export.csv`;
123
+
124
+ return {
125
+ filename: filename.endsWith('.csv') ? filename : `${filename}.csv`,
126
+ csv: buffer.toString('utf8'),
127
+ base64: buffer.toString('base64'),
128
+ size: buffer.length,
129
+ mimeType: CSV_MIME_TYPE,
130
+ };
131
+ },
132
+ },
133
+ };
134
+ }
135
+
136
+ module.exports = {
137
+ createCsvServices,
138
+ };