frappebun 0.0.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.
- package/README.md +72 -0
- package/package.json +59 -0
- package/src/api/auth.ts +76 -0
- package/src/api/index.ts +10 -0
- package/src/api/resource.ts +177 -0
- package/src/api/route.ts +301 -0
- package/src/app/index.ts +6 -0
- package/src/app/loader.ts +218 -0
- package/src/auth/auth.ts +247 -0
- package/src/auth/index.ts +2 -0
- package/src/cli/args.ts +40 -0
- package/src/cli/bin.ts +12 -0
- package/src/cli/commands/add-api.ts +32 -0
- package/src/cli/commands/add-doctype.ts +43 -0
- package/src/cli/commands/add-page.ts +33 -0
- package/src/cli/commands/add-user.ts +96 -0
- package/src/cli/commands/dev.ts +71 -0
- package/src/cli/commands/drop-site.ts +27 -0
- package/src/cli/commands/init.ts +98 -0
- package/src/cli/commands/migrate.ts +110 -0
- package/src/cli/commands/new-site.ts +61 -0
- package/src/cli/commands/routes.ts +56 -0
- package/src/cli/commands/use.ts +30 -0
- package/src/cli/index.ts +73 -0
- package/src/cli/log.ts +13 -0
- package/src/cli/scaffold/templates.ts +189 -0
- package/src/context.ts +162 -0
- package/src/core/doctype/migration/migration.ts +17 -0
- package/src/core/doctype/role/role.ts +7 -0
- package/src/core/doctype/session/session.ts +16 -0
- package/src/core/doctype/user/user.controller.ts +11 -0
- package/src/core/doctype/user/user.ts +22 -0
- package/src/core/doctype/user_role/user_role.ts +9 -0
- package/src/core/doctypes.ts +25 -0
- package/src/core/index.ts +1 -0
- package/src/database/database.ts +359 -0
- package/src/database/filters.ts +131 -0
- package/src/database/index.ts +30 -0
- package/src/database/query-builder.ts +1118 -0
- package/src/database/schema.ts +188 -0
- package/src/doctype/define.ts +45 -0
- package/src/doctype/discovery.ts +57 -0
- package/src/doctype/field.ts +160 -0
- package/src/doctype/index.ts +20 -0
- package/src/doctype/layout.ts +62 -0
- package/src/doctype/query-builder-stub.ts +16 -0
- package/src/doctype/registry.ts +106 -0
- package/src/doctype/types.ts +407 -0
- package/src/document/document.ts +593 -0
- package/src/document/index.ts +6 -0
- package/src/document/naming.ts +56 -0
- package/src/errors.ts +53 -0
- package/src/frappe.d.ts +128 -0
- package/src/globals.ts +72 -0
- package/src/index.ts +112 -0
- package/src/migrations/index.ts +11 -0
- package/src/migrations/runner.ts +256 -0
- package/src/permissions/index.ts +265 -0
- package/src/response.ts +100 -0
- package/src/server.ts +210 -0
- package/src/site.ts +126 -0
- package/src/ssr/handler.ts +56 -0
- package/src/ssr/index.ts +11 -0
- package/src/ssr/page-loader.ts +200 -0
- package/src/ssr/renderer.ts +94 -0
- package/src/ssr/use-context.ts +41 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript types for DocType schema definitions.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { QueryBuilderLike } from "./query-builder-stub"
|
|
6
|
+
|
|
7
|
+
export type Dict = Record<string, unknown>
|
|
8
|
+
|
|
9
|
+
// ─── Filter types ─────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
export type FilterValue = string | number | boolean | null
|
|
12
|
+
export type FilterOperator =
|
|
13
|
+
| "="
|
|
14
|
+
| "!="
|
|
15
|
+
| ">"
|
|
16
|
+
| "<"
|
|
17
|
+
| ">="
|
|
18
|
+
| "<="
|
|
19
|
+
| "like"
|
|
20
|
+
| "not like"
|
|
21
|
+
| "in"
|
|
22
|
+
| "not in"
|
|
23
|
+
| "between"
|
|
24
|
+
| "is"
|
|
25
|
+
export type FilterCondition = [FilterOperator, FilterValue | FilterValue[]]
|
|
26
|
+
export type ObjectFilter = Record<string, FilterValue | FilterCondition | null>
|
|
27
|
+
// ArrayFilter is recursive; using a flat tuple + rest keeps TypeScript happy
|
|
28
|
+
export type ArrayFilter = [string, ...(ObjectFilter | ArrayFilter | unknown)[]]
|
|
29
|
+
export type FilterInput = ObjectFilter | ArrayFilter | null | undefined
|
|
30
|
+
|
|
31
|
+
// ─── Document interface (for hooks & computed fields) ──────
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The document API surface exposed to controllers and field functions.
|
|
35
|
+
* The concrete `Document` class implements this.
|
|
36
|
+
*/
|
|
37
|
+
export interface DocumentLike {
|
|
38
|
+
readonly name: string
|
|
39
|
+
readonly doctype: string
|
|
40
|
+
owner: string
|
|
41
|
+
creation: string
|
|
42
|
+
modified: string
|
|
43
|
+
modifiedBy: string
|
|
44
|
+
docstatus: 0 | 1 | 2
|
|
45
|
+
idx: number
|
|
46
|
+
parent?: string
|
|
47
|
+
parentType?: string
|
|
48
|
+
parentField?: string
|
|
49
|
+
|
|
50
|
+
isNew(): boolean
|
|
51
|
+
isModified(field?: string): boolean
|
|
52
|
+
|
|
53
|
+
get(field: string): unknown
|
|
54
|
+
set(field: string, value: unknown): void
|
|
55
|
+
getDbValue(field: string): Promise<unknown>
|
|
56
|
+
|
|
57
|
+
insert(): Promise<this>
|
|
58
|
+
save(): Promise<this>
|
|
59
|
+
submit(): Promise<this>
|
|
60
|
+
cancel(): Promise<this>
|
|
61
|
+
delete(): Promise<void>
|
|
62
|
+
reload(): Promise<this>
|
|
63
|
+
|
|
64
|
+
append(field: string, data?: Dict): DocumentLike
|
|
65
|
+
remove(field: string, row: DocumentLike): void
|
|
66
|
+
addComment(text: string, commentType?: string): Promise<void>
|
|
67
|
+
|
|
68
|
+
asDict(): Dict
|
|
69
|
+
getValidDict(): Dict
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ─── Field Types ──────────────────────────────────────────
|
|
73
|
+
|
|
74
|
+
export type FieldType =
|
|
75
|
+
| "Data"
|
|
76
|
+
| "Int"
|
|
77
|
+
| "Float"
|
|
78
|
+
| "Currency"
|
|
79
|
+
| "Percent"
|
|
80
|
+
| "Check"
|
|
81
|
+
| "Rating"
|
|
82
|
+
| "Text"
|
|
83
|
+
| "SmallText"
|
|
84
|
+
| "LongText"
|
|
85
|
+
| "TextEditor"
|
|
86
|
+
| "MarkdownEditor"
|
|
87
|
+
| "Code"
|
|
88
|
+
| "HtmlEditor"
|
|
89
|
+
| "JSON"
|
|
90
|
+
| "Date"
|
|
91
|
+
| "Datetime"
|
|
92
|
+
| "Time"
|
|
93
|
+
| "Duration"
|
|
94
|
+
| "Select"
|
|
95
|
+
| "Link"
|
|
96
|
+
| "DynamicLink"
|
|
97
|
+
| "TableMultiSelect"
|
|
98
|
+
| "Table"
|
|
99
|
+
| "Attach"
|
|
100
|
+
| "AttachImage"
|
|
101
|
+
| "Image"
|
|
102
|
+
| "Color"
|
|
103
|
+
| "Signature"
|
|
104
|
+
| "Geolocation"
|
|
105
|
+
| "Password"
|
|
106
|
+
| "ReadOnly"
|
|
107
|
+
| "HtmlField"
|
|
108
|
+
|
|
109
|
+
export interface FieldOptions {
|
|
110
|
+
label?: string
|
|
111
|
+
required?: boolean
|
|
112
|
+
unique?: boolean
|
|
113
|
+
default?: unknown
|
|
114
|
+
readOnly?: boolean
|
|
115
|
+
hidden?: boolean
|
|
116
|
+
description?: string
|
|
117
|
+
maxLength?: number
|
|
118
|
+
options?: string
|
|
119
|
+
|
|
120
|
+
// List/filter settings
|
|
121
|
+
inListView?: boolean
|
|
122
|
+
inStandardFilter?: boolean
|
|
123
|
+
inGlobalSearch?: boolean
|
|
124
|
+
|
|
125
|
+
// Fetch from linked doc
|
|
126
|
+
fetchFrom?: string
|
|
127
|
+
|
|
128
|
+
// Numeric options
|
|
129
|
+
nonNegative?: boolean
|
|
130
|
+
precision?: number
|
|
131
|
+
|
|
132
|
+
// Computed field — runs on every save
|
|
133
|
+
computed?: (doc: DocumentLike) => unknown
|
|
134
|
+
|
|
135
|
+
// Conditional visibility
|
|
136
|
+
visibleIf?: (doc: DocumentLike) => boolean
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface FieldDefinition {
|
|
140
|
+
type: FieldType
|
|
141
|
+
label?: string
|
|
142
|
+
required?: boolean
|
|
143
|
+
unique?: boolean
|
|
144
|
+
default?: unknown
|
|
145
|
+
readOnly?: boolean
|
|
146
|
+
hidden?: boolean
|
|
147
|
+
description?: string
|
|
148
|
+
maxLength?: number
|
|
149
|
+
options?: string | string[]
|
|
150
|
+
|
|
151
|
+
inListView?: boolean
|
|
152
|
+
inStandardFilter?: boolean
|
|
153
|
+
inGlobalSearch?: boolean
|
|
154
|
+
fetchFrom?: string
|
|
155
|
+
nonNegative?: boolean
|
|
156
|
+
precision?: number
|
|
157
|
+
computed?: (doc: DocumentLike) => unknown
|
|
158
|
+
visibleIf?: (doc: DocumentLike) => boolean
|
|
159
|
+
|
|
160
|
+
// For Link fields
|
|
161
|
+
doctype?: string
|
|
162
|
+
|
|
163
|
+
// For DynamicLink fields
|
|
164
|
+
linkField?: string
|
|
165
|
+
|
|
166
|
+
// For Table fields
|
|
167
|
+
childDocType?: string
|
|
168
|
+
childFields?: Record<string, FieldDefinition>
|
|
169
|
+
|
|
170
|
+
// For Select fields
|
|
171
|
+
selectOptions?: string[]
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ─── Layout Types ──────────────────────────────────────────
|
|
175
|
+
|
|
176
|
+
export interface LayoutColumn {
|
|
177
|
+
_type: "column"
|
|
178
|
+
fields: string[]
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export interface LayoutSection {
|
|
182
|
+
_type: "section"
|
|
183
|
+
title?: string
|
|
184
|
+
collapsible?: boolean
|
|
185
|
+
description?: string
|
|
186
|
+
columns?: LayoutColumn[]
|
|
187
|
+
fields?: string[]
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export interface LayoutTab {
|
|
191
|
+
_type: "tab"
|
|
192
|
+
label: string
|
|
193
|
+
sections: LayoutSection[]
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export type LayoutEntry = LayoutSection | LayoutTab | string[]
|
|
197
|
+
|
|
198
|
+
// ─── Permission Types ──────────────────────────────────────
|
|
199
|
+
|
|
200
|
+
export interface PermissionRule {
|
|
201
|
+
role: string
|
|
202
|
+
read?: boolean
|
|
203
|
+
write?: boolean
|
|
204
|
+
create?: boolean
|
|
205
|
+
delete?: boolean
|
|
206
|
+
submit?: boolean
|
|
207
|
+
cancel?: boolean
|
|
208
|
+
amend?: boolean
|
|
209
|
+
print?: boolean
|
|
210
|
+
email?: boolean
|
|
211
|
+
report?: boolean
|
|
212
|
+
import?: boolean
|
|
213
|
+
export?: boolean
|
|
214
|
+
share?: boolean
|
|
215
|
+
condition?: Dict
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// ─── List Configuration ─────────────────────────────────────
|
|
219
|
+
|
|
220
|
+
export interface ListConfig {
|
|
221
|
+
fields?: string[]
|
|
222
|
+
filters?: string[]
|
|
223
|
+
orderBy?: string
|
|
224
|
+
titleField?: string
|
|
225
|
+
searchFields?: string[]
|
|
226
|
+
subjectField?: string
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ─── Search Configuration ───────────────────────────────────
|
|
230
|
+
|
|
231
|
+
export interface SearchConfig {
|
|
232
|
+
indexed?: string[]
|
|
233
|
+
boost?: Record<string, number>
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// ─── Workflow ───────────────────────────────────────────────
|
|
237
|
+
|
|
238
|
+
export interface WorkflowState {
|
|
239
|
+
name: string
|
|
240
|
+
style?: "secondary" | "warning" | "success" | "danger" | "info" | "primary"
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export interface WorkflowTransition {
|
|
244
|
+
from: string
|
|
245
|
+
to: string
|
|
246
|
+
by: string
|
|
247
|
+
action: string
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface WorkflowConfig {
|
|
251
|
+
stateField: string
|
|
252
|
+
states: WorkflowState[]
|
|
253
|
+
transitions: WorkflowTransition[]
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ─── DocType Schema ─────────────────────────────────────────
|
|
257
|
+
|
|
258
|
+
export type NamingStrategy =
|
|
259
|
+
| "autoincrement"
|
|
260
|
+
| "uuid"
|
|
261
|
+
| "hash"
|
|
262
|
+
| "prompt"
|
|
263
|
+
| `series:${string}`
|
|
264
|
+
| `field:${string}`
|
|
265
|
+
|
|
266
|
+
export interface RestConfig {
|
|
267
|
+
list?: boolean
|
|
268
|
+
read?: boolean
|
|
269
|
+
create?: boolean
|
|
270
|
+
update?: boolean
|
|
271
|
+
delete?: boolean
|
|
272
|
+
submit?: boolean
|
|
273
|
+
cancel?: boolean
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface DocTypeSchema {
|
|
277
|
+
naming?: NamingStrategy
|
|
278
|
+
module?: string
|
|
279
|
+
isSingle?: boolean
|
|
280
|
+
isSubmittable?: boolean
|
|
281
|
+
isTree?: boolean
|
|
282
|
+
isVirtual?: boolean
|
|
283
|
+
isChild?: boolean
|
|
284
|
+
trackChanges?: boolean
|
|
285
|
+
|
|
286
|
+
fields: Record<string, FieldDefinition>
|
|
287
|
+
layout?: LayoutEntry[]
|
|
288
|
+
permissions?: PermissionRule[]
|
|
289
|
+
list?: ListConfig
|
|
290
|
+
search?: SearchConfig
|
|
291
|
+
workflow?: WorkflowConfig
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Expose this DocType over the REST API.
|
|
295
|
+
* `true` enables all endpoints; an object selectively enables specific operations.
|
|
296
|
+
*/
|
|
297
|
+
rest?: boolean | RestConfig
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export interface DocTypeDefinition {
|
|
301
|
+
name: string
|
|
302
|
+
schema: DocTypeSchema
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// ─── Permissions Block (in controller) ──────────────────────
|
|
306
|
+
|
|
307
|
+
/** Returned by `frappe.perms.deny(message)` to signal a contextual denial. */
|
|
308
|
+
export interface PermissionDenial {
|
|
309
|
+
__type: "PermissionDenial"
|
|
310
|
+
message: string
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export type PermCheckResult = boolean | PermissionDenial | Promise<boolean | PermissionDenial>
|
|
314
|
+
|
|
315
|
+
export interface PermissionsBlock {
|
|
316
|
+
/**
|
|
317
|
+
* Row-level scope: return a QueryBuilder to restrict the list, or null for no restriction.
|
|
318
|
+
* Called on every list query for this DocType.
|
|
319
|
+
*/
|
|
320
|
+
scope?: (user: string) => QueryBuilderLike | null
|
|
321
|
+
|
|
322
|
+
/** Called before `doc.insert()`. Return false / deny() to block. */
|
|
323
|
+
create?: (user: string) => PermCheckResult
|
|
324
|
+
|
|
325
|
+
/** Called after `frappe.getDoc()`. Return false / deny() to block. */
|
|
326
|
+
read?: (doc: DocumentLike, user: string) => PermCheckResult
|
|
327
|
+
|
|
328
|
+
/** Called before `doc.save()`. Return false / deny() to block. */
|
|
329
|
+
write?: (doc: DocumentLike, user: string) => PermCheckResult
|
|
330
|
+
|
|
331
|
+
/** Called before `doc.delete()`. Return false / deny() to block. */
|
|
332
|
+
delete?: (doc: DocumentLike, user: string) => PermCheckResult
|
|
333
|
+
|
|
334
|
+
/** Called before `doc.submit()`. */
|
|
335
|
+
submit?: (doc: DocumentLike, user: string) => PermCheckResult
|
|
336
|
+
|
|
337
|
+
/** Called before `doc.cancel()`. */
|
|
338
|
+
cancel?: (doc: DocumentLike, user: string) => PermCheckResult
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// ─── Controller Types ───────────────────────────────────────
|
|
342
|
+
|
|
343
|
+
export interface ControllerHooks {
|
|
344
|
+
beforeInsert?: (doc: DocumentLike) => Promise<void> | void
|
|
345
|
+
validate?: (doc: DocumentLike) => Promise<void> | void
|
|
346
|
+
afterInsert?: (doc: DocumentLike) => Promise<void> | void
|
|
347
|
+
beforeSave?: (doc: DocumentLike) => Promise<void> | void
|
|
348
|
+
onUpdate?: (doc: DocumentLike) => Promise<void> | void
|
|
349
|
+
afterSave?: (doc: DocumentLike) => Promise<void> | void
|
|
350
|
+
beforeSubmit?: (doc: DocumentLike) => Promise<void> | void
|
|
351
|
+
onSubmit?: (doc: DocumentLike) => Promise<void> | void
|
|
352
|
+
beforeCancel?: (doc: DocumentLike) => Promise<void> | void
|
|
353
|
+
onCancel?: (doc: DocumentLike) => Promise<void> | void
|
|
354
|
+
onTrash?: (doc: DocumentLike) => Promise<void> | void
|
|
355
|
+
onLoad?: (doc: DocumentLike) => Promise<void> | void
|
|
356
|
+
|
|
357
|
+
methods?: Record<string, (doc: DocumentLike, ...args: unknown[]) => Promise<unknown> | unknown>
|
|
358
|
+
|
|
359
|
+
/** Permissions block: scope and per-action document checks. */
|
|
360
|
+
permissions?: PermissionsBlock
|
|
361
|
+
|
|
362
|
+
getPermissionQuery?: (user: string) => FilterInput
|
|
363
|
+
hasPermission?: (doc: DocumentLike, ptype: string, user: string) => boolean | Promise<boolean>
|
|
364
|
+
|
|
365
|
+
onTransition?: Record<string, (doc: DocumentLike) => Promise<void> | void>
|
|
366
|
+
|
|
367
|
+
// Virtual DocType methods
|
|
368
|
+
getList?: (args: unknown) => Promise<Dict[]>
|
|
369
|
+
getCount?: (args: unknown) => Promise<number>
|
|
370
|
+
loadFromDb?: (doc: DocumentLike) => Promise<void>
|
|
371
|
+
dbInsert?: (doc: DocumentLike) => Promise<void>
|
|
372
|
+
dbUpdate?: (doc: DocumentLike) => Promise<void>
|
|
373
|
+
dbDelete?: (doc: DocumentLike) => Promise<void>
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
export interface ControllerDefinition {
|
|
377
|
+
name: string
|
|
378
|
+
hooks: ControllerHooks
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// ─── Reserved field names ───────────────────────────────────
|
|
382
|
+
|
|
383
|
+
export const RESERVED_FIELD_NAMES = new Set([
|
|
384
|
+
"name",
|
|
385
|
+
"owner",
|
|
386
|
+
"creation",
|
|
387
|
+
"modified",
|
|
388
|
+
"modifiedBy",
|
|
389
|
+
"docstatus",
|
|
390
|
+
"idx",
|
|
391
|
+
"parent",
|
|
392
|
+
"parentType",
|
|
393
|
+
"parentField",
|
|
394
|
+
"doctype",
|
|
395
|
+
])
|
|
396
|
+
|
|
397
|
+
export const STANDARD_FIELDS = [
|
|
398
|
+
"name",
|
|
399
|
+
"creation",
|
|
400
|
+
"modified",
|
|
401
|
+
"modifiedBy",
|
|
402
|
+
"owner",
|
|
403
|
+
"docstatus",
|
|
404
|
+
"idx",
|
|
405
|
+
] as const
|
|
406
|
+
|
|
407
|
+
export const CHILD_STANDARD_FIELDS = ["parent", "parentType", "parentField"] as const
|