-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathfield-zoo.object.ts
More file actions
142 lines (127 loc) · 7.7 KB
/
Copy pathfield-zoo.object.ts
File metadata and controls
142 lines (127 loc) · 7.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
import { ObjectSchema, Field } from '@objectstack/spec/data';
import { cel } from '@objectstack/spec';
/**
* Field Zoo — one field of (almost) every `FieldType` the protocol defines.
*
* This is a synthetic "standard" object whose only job is exhaustive
* data-layer coverage: the {@link COVERAGE} manifest and the coverage test
* assert that every member of `FieldTypeSchema` appears at least once across
* the stack, and this object carries the bulk of them. Builder helpers
* (`Field.text(...)`) are used where they exist; the remaining types are
* declared as raw `{ type, ... }` literals (the field input is
* `Omit<Partial<Field>, 'type'>`, so any valid type string is accepted).
*
* Relationship types (`lookup`, `master_detail`, `tree`) point at the other
* showcase objects so $expand and hierarchy resolution have real targets.
*/
export const FieldZoo = ObjectSchema.create({
name: 'showcase_field_zoo',
// [ADR-0090 D1] Explicit grandfather stamp: record isolation for this demo
// object is RLS-owned / intentionally public; without this the new secure
// default (unset OWD => private) would owner-filter it.
sharingModel: 'public_read_write',
label: 'Field Zoo',
pluralLabel: 'Field Zoo',
icon: 'shapes',
description: 'One field of every supported type — exhaustive data-layer coverage.',
fields: {
// ── Core text ───────────────────────────────────────────────────────
name: Field.text({ label: 'Name', required: true, searchable: true, maxLength: 200 }),
f_textarea: Field.textarea({ label: 'Textarea' }),
f_email: Field.email({ label: 'Email', searchable: true }),
f_url: Field.url({ label: 'URL' }),
f_phone: Field.phone({ label: 'Phone' }),
f_password: Field.password({ label: 'Password (masked on read)' }),
f_secret: Field.secret({ label: 'Secret (encrypted at rest)' }),
// ── Rich content ─────────────────────────────────────────────────────
f_markdown: Field.markdown({ label: 'Markdown' }),
f_html: Field.html({ label: 'HTML' }),
f_richtext: Field.richtext({ label: 'Rich Text' }),
// ── Numbers ──────────────────────────────────────────────────────────
f_number: Field.number({ label: 'Number', min: 0, max: 1000 }),
f_currency: Field.currency({ label: 'Currency', scale: 2, min: 0, currencyConfig: { currencyMode: 'fixed', defaultCurrency: 'USD', precision: 2 } }),
f_percent: Field.percent({ label: 'Percent', min: 0, max: 100, defaultValue: 50 }),
// ── Date & time ──────────────────────────────────────────────────────
f_date: Field.date({ label: 'Date' }),
f_datetime: Field.datetime({ label: 'Date / Time' }),
f_time: { type: 'time', label: 'Time' },
// ── Logic ────────────────────────────────────────────────────────────
f_boolean: Field.boolean({ label: 'Boolean' }),
f_toggle: { type: 'toggle', label: 'Toggle', defaultValue: false },
// ── Selection ────────────────────────────────────────────────────────
f_select: Field.select({
label: 'Select',
options: [
{ label: 'Low', value: 'low', default: true, color: '#94A3B8' },
{ label: 'Medium', value: 'medium', color: '#F59E0B' },
{ label: 'High', value: 'high', color: '#EF4444' },
],
}),
f_multiselect: {
type: 'multiselect',
label: 'Multi-select',
options: [
{ label: 'Red', value: 'red' },
{ label: 'Green', value: 'green' },
{ label: 'Blue', value: 'blue' },
],
},
f_radio: {
type: 'radio',
label: 'Radio',
options: [
{ label: 'Yes', value: 'yes' },
{ label: 'No', value: 'no' },
],
},
f_checkboxes: {
type: 'checkboxes',
label: 'Checkboxes',
options: [
{ label: 'Email', value: 'email' },
{ label: 'SMS', value: 'sms' },
{ label: 'Push', value: 'push' },
],
},
f_tags: { type: 'tags', label: 'Tags' },
// ── Relational ───────────────────────────────────────────────────────
f_lookup: Field.lookup('showcase_account', { label: 'Lookup → Account' }),
f_master_detail: Field.masterDetail('showcase_project', { label: 'Master-Detail → Project' }),
f_tree: { type: 'tree', label: 'Tree (self/category)', reference: 'showcase_category' },
// ── User (lookup specialized to sys_user) ────────────────────────────
f_user: Field.user({ label: 'User → sys_user (single)' }),
f_users: Field.user({ label: 'Users (multiple)', multiple: true }),
f_owner: Field.user({ label: 'Owner (current_user default)', defaultValue: 'current_user' }),
// ── Media ────────────────────────────────────────────────────────────
f_image: Field.image({ label: 'Image' }),
f_file: Field.file({ label: 'File' }),
f_avatar: Field.avatar({ label: 'Avatar' }),
f_video: { type: 'video', label: 'Video' },
f_audio: { type: 'audio', label: 'Audio' },
// ── Calculated / system ──────────────────────────────────────────────
f_formula: Field.formula({
label: 'Formula (number × percent)',
expression: cel`(record.f_number == null ? 0 : record.f_number) * (record.f_percent == null ? 0 : record.f_percent) / 100`,
}),
f_summary: Field.summary({ label: 'Roll-up Summary' }),
f_autonumber: Field.autonumber({ label: 'Auto Number' }),
// ── Embedded structured values (stored as JSON on the row) ───────────
f_composite: { type: 'composite', label: 'Composite (embedded object)' },
f_repeater: { type: 'repeater', label: 'Repeater (embedded array)' },
f_record: { type: 'record', label: 'Record (name-keyed map)' },
// ── Enhanced types ───────────────────────────────────────────────────
f_location: Field.location({ label: 'Location (GPS)' }),
f_address: Field.address({ label: 'Address' }),
f_code: Field.code('json', { label: 'Code Editor' }),
f_json: Field.json({ label: 'JSON' }),
f_color: Field.color({ label: 'Color' }),
f_rating: { type: 'rating', label: 'Rating', max: 5 },
f_slider: Field.slider({ label: 'Slider', min: 0, max: 100, step: 5 }),
f_signature: Field.signature({ label: 'Signature' }),
f_qrcode: Field.qrcode({ label: 'QR / Barcode' }),
f_progress: { type: 'progress', label: 'Progress', min: 0, max: 100 },
// ── AI / ML ──────────────────────────────────────────────────────────
f_vector: { type: 'vector', label: 'Embedding Vector', dimensions: 1536 },
},
});