@loj-lang/cli 0.5.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 +87 -0
- package/agent-assets/loj-authoring/SKILL.md +179 -0
- package/agent-assets/loj-authoring/agents/openai.yaml +3 -0
- package/agent-assets/loj-authoring/metadata.json +6 -0
- package/agent-assets/loj-authoring/references/backend-family.md +340 -0
- package/agent-assets/loj-authoring/references/backend-targets.md +171 -0
- package/agent-assets/loj-authoring/references/frontend-family.md +794 -0
- package/agent-assets/loj-authoring/references/frontend-runtime-trace.md +204 -0
- package/agent-assets/loj-authoring/references/policy-rules-proof.md +178 -0
- package/agent-assets/loj-authoring/references/project-and-transport.md +454 -0
- package/agent-assets/loj-authoring/references/workflow-flow-proof.md +263 -0
- package/dist/database-native-sql.d.ts +4 -0
- package/dist/database-native-sql.d.ts.map +1 -0
- package/dist/database-native-sql.js +266 -0
- package/dist/database-native-sql.js.map +1 -0
- package/dist/env.d.ts +31 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +229 -0
- package/dist/env.js.map +1 -0
- package/dist/fastapi-dev-runner.d.ts +3 -0
- package/dist/fastapi-dev-runner.d.ts.map +1 -0
- package/dist/fastapi-dev-runner.js +263 -0
- package/dist/fastapi-dev-runner.js.map +1 -0
- package/dist/flow-proof.d.ts +3 -0
- package/dist/flow-proof.d.ts.map +1 -0
- package/dist/flow-proof.js +2 -0
- package/dist/flow-proof.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5353 -0
- package/dist/index.js.map +1 -0
- package/dist/rules-proof.d.ts +3 -0
- package/dist/rules-proof.d.ts.map +1 -0
- package/dist/rules-proof.js +2 -0
- package/dist/rules-proof.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Frontend Runtime And Trace
|
|
2
|
+
|
|
3
|
+
Use this reference when the task involves generated React code, runtime assumptions, `rdsl inspect`,
|
|
4
|
+
or `rdsl trace`.
|
|
5
|
+
|
|
6
|
+
## Current Generated Target
|
|
7
|
+
|
|
8
|
+
- frontend-family currently generates `react + typescript`
|
|
9
|
+
- generated code imports direct subpaths from `@loj-lang/rdsl-runtime`
|
|
10
|
+
- generated code should not assume a barrel-export-only runtime contract
|
|
11
|
+
|
|
12
|
+
Current direct runtime import families used by generated code include:
|
|
13
|
+
|
|
14
|
+
- components:
|
|
15
|
+
- `DataTable`
|
|
16
|
+
- `GroupedDataTable`
|
|
17
|
+
- `PivotDataTable`
|
|
18
|
+
- `FilterBar`
|
|
19
|
+
- `Pagination`
|
|
20
|
+
- `FormField`
|
|
21
|
+
- `ConfirmDialog`
|
|
22
|
+
- `WorkflowSummary`
|
|
23
|
+
- hooks:
|
|
24
|
+
- `useResource`
|
|
25
|
+
- `useReadModel`
|
|
26
|
+
- `useCollectionView`
|
|
27
|
+
- `useGroupedCollectionView`
|
|
28
|
+
- `useToast`
|
|
29
|
+
- `useAuth`
|
|
30
|
+
- `useDocumentMetadata`
|
|
31
|
+
- navigation helpers under `hooks/navigation`
|
|
32
|
+
- policy helper:
|
|
33
|
+
- `can`
|
|
34
|
+
|
|
35
|
+
## Runtime Assumptions
|
|
36
|
+
|
|
37
|
+
### `useResource(api)`
|
|
38
|
+
|
|
39
|
+
Generated CRUD flows assume `useResource` provides:
|
|
40
|
+
|
|
41
|
+
- `data`
|
|
42
|
+
- `allData`
|
|
43
|
+
- `loading`
|
|
44
|
+
- `error`
|
|
45
|
+
- `filters`, `setFilters`
|
|
46
|
+
- `sort`, `setSort`
|
|
47
|
+
- `pagination`, `setPagination`
|
|
48
|
+
- `getById`
|
|
49
|
+
- `createItem`
|
|
50
|
+
- `updateItem`
|
|
51
|
+
- `deleteItem`
|
|
52
|
+
- `refresh`
|
|
53
|
+
|
|
54
|
+
Resource records always have `id: string` at the frontend runtime surface.
|
|
55
|
+
|
|
56
|
+
Generated relation/page reuse still depends on `allData` for:
|
|
57
|
+
|
|
58
|
+
- relation-derived projections such as `team.name` / `members.count`
|
|
59
|
+
- record-scoped relation page filtering by inverse foreign key
|
|
60
|
+
- relation-aware create/edit/read back-link reuse
|
|
61
|
+
|
|
62
|
+
### `useReadModel(api, options)`
|
|
63
|
+
|
|
64
|
+
Generated read-model pages assume a fixed GET list-style contract and current helper behavior for:
|
|
65
|
+
|
|
66
|
+
- `data`
|
|
67
|
+
- `loading`
|
|
68
|
+
- `error`
|
|
69
|
+
- URL-backed query inputs
|
|
70
|
+
- required-input gating before fetch
|
|
71
|
+
|
|
72
|
+
Current read-model pages may also layer:
|
|
73
|
+
|
|
74
|
+
- shared `queryState`
|
|
75
|
+
- `dateNavigation`
|
|
76
|
+
- `selectionState`
|
|
77
|
+
- grouped/pivoted table presentation over fetched rows
|
|
78
|
+
|
|
79
|
+
### `useCollectionView(items, options)` / `useGroupedCollectionView(items, options)`
|
|
80
|
+
|
|
81
|
+
Generated list, related-panel, page-table, grouped-table, and grouped-matrix surfaces assume these
|
|
82
|
+
helpers provide:
|
|
83
|
+
|
|
84
|
+
- `data`
|
|
85
|
+
- `filters`, `setFilters`
|
|
86
|
+
- `sort`, `setSort`
|
|
87
|
+
- `pagination`, `setPagination`
|
|
88
|
+
|
|
89
|
+
Current rule:
|
|
90
|
+
|
|
91
|
+
- filtering, sorting, grouping, pivoting, and pagination are currently client-side after fetch
|
|
92
|
+
- relation-derived filters and sortable relation columns are applied over projected table data, not
|
|
93
|
+
server-side joins
|
|
94
|
+
|
|
95
|
+
### `useToast()`
|
|
96
|
+
|
|
97
|
+
Generated code may call:
|
|
98
|
+
|
|
99
|
+
- `toast.success("Saved!")`
|
|
100
|
+
- `toast.success({ key, defaultMessage, values })`
|
|
101
|
+
|
|
102
|
+
Descriptor values stay scalar/deterministic.
|
|
103
|
+
|
|
104
|
+
### `useDocumentMetadata()`
|
|
105
|
+
|
|
106
|
+
Generated web metadata surfaces now assume runtime support for:
|
|
107
|
+
|
|
108
|
+
- `document.title`
|
|
109
|
+
- meta `description`
|
|
110
|
+
- canonical link
|
|
111
|
+
- `og:*` image/title/description-ish fields
|
|
112
|
+
- favicon
|
|
113
|
+
|
|
114
|
+
That support is driven by `.web.loj` `app.seo`, `page.seo`, and `@asset(...)`, not by ad hoc host code.
|
|
115
|
+
|
|
116
|
+
### Navigation helpers
|
|
117
|
+
|
|
118
|
+
Generated code now assumes runtime helpers for:
|
|
119
|
+
|
|
120
|
+
- app-local href construction
|
|
121
|
+
- sanitized `returnTo`
|
|
122
|
+
- current location/search parsing
|
|
123
|
+
- optional web `runtime.basePath` stripping/prefixing
|
|
124
|
+
|
|
125
|
+
Do not hand-edit generated code to bypass those helpers.
|
|
126
|
+
|
|
127
|
+
### `can(rule, context)`
|
|
128
|
+
|
|
129
|
+
Generated code uses `can()` only for built-in normalized rule ASTs.
|
|
130
|
+
|
|
131
|
+
It currently gates:
|
|
132
|
+
|
|
133
|
+
- `visibleIf`
|
|
134
|
+
- `enabledIf`
|
|
135
|
+
- linked grouped-rule eligibility/validation surfaces
|
|
136
|
+
- navigation visibility
|
|
137
|
+
- workflow step visibility
|
|
138
|
+
|
|
139
|
+
## Runtime Transport Baseline
|
|
140
|
+
|
|
141
|
+
The current frontend runtime accepts list responses shaped as:
|
|
142
|
+
|
|
143
|
+
- raw array
|
|
144
|
+
- `{ items: [...] }`
|
|
145
|
+
- `{ data: [...] }`
|
|
146
|
+
|
|
147
|
+
Single-record responses may be:
|
|
148
|
+
|
|
149
|
+
- raw object
|
|
150
|
+
- `{ item: {...} }`
|
|
151
|
+
- `{ data: {...} }`
|
|
152
|
+
|
|
153
|
+
Errors may be:
|
|
154
|
+
|
|
155
|
+
- non-2xx JSON with string `message`
|
|
156
|
+
|
|
157
|
+
Important current rule:
|
|
158
|
+
|
|
159
|
+
- server-driven pagination metadata is not required
|
|
160
|
+
- list pagination is currently derived client-side after fetch
|
|
161
|
+
|
|
162
|
+
## Browser Events
|
|
163
|
+
|
|
164
|
+
Generated code may emit:
|
|
165
|
+
|
|
166
|
+
- `rdsl:refresh`
|
|
167
|
+
- `rdsl:invalidate`
|
|
168
|
+
- `rdsl:open-dialog`
|
|
169
|
+
|
|
170
|
+
These are still part of generated-code/runtime integration.
|
|
171
|
+
|
|
172
|
+
## Trace And Inspect
|
|
173
|
+
|
|
174
|
+
Use:
|
|
175
|
+
|
|
176
|
+
- `rdsl inspect <entry.web.loj|build-dir> [--node <id>]`
|
|
177
|
+
- `rdsl trace <entry-or-build-dir> <generated-file:line[:col]>`
|
|
178
|
+
|
|
179
|
+
Current manifest split:
|
|
180
|
+
|
|
181
|
+
- `semantic-manifest.json`
|
|
182
|
+
- `trace-manifest.json`
|
|
183
|
+
|
|
184
|
+
Important trace concepts:
|
|
185
|
+
|
|
186
|
+
- `sourceFiles`
|
|
187
|
+
- `generatedFiles`
|
|
188
|
+
- `nodes`
|
|
189
|
+
- `regions`
|
|
190
|
+
- `hostFiles`
|
|
191
|
+
|
|
192
|
+
What they mean:
|
|
193
|
+
|
|
194
|
+
- `nodes`: semantic node catalog
|
|
195
|
+
- `regions`: generated file spans mapped back to semantic nodes
|
|
196
|
+
- `hostFiles`: copied escape-hatch files plus copied dependencies such as CSS and asset closures
|
|
197
|
+
|
|
198
|
+
## Authoring Guardrails
|
|
199
|
+
|
|
200
|
+
- When reviewing generated React code, validate it against these runtime contracts, not ad hoc
|
|
201
|
+
assumptions.
|
|
202
|
+
- If a task is about generated-output bugs, check runtime contract mismatches first.
|
|
203
|
+
- If a task is about trace/inspect behavior, reason in terms of `semantic node -> generated region`,
|
|
204
|
+
not line comments alone.
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Policy / Rules Proof (`.rules.loj`)
|
|
2
|
+
|
|
3
|
+
Use this reference only for the current first-slice rules proof.
|
|
4
|
+
|
|
5
|
+
This is still a narrow surface. It is now wired into backend-family `.api.loj` through:
|
|
6
|
+
|
|
7
|
+
- `resource auth.policy: '@rules("./policies/x")'`
|
|
8
|
+
- `resource create.rules: '@rules("./rules/x")'`
|
|
9
|
+
- `readModel <name> rules: '@rules("./rules/x")'`
|
|
10
|
+
|
|
11
|
+
It is now also wired into frontend-family `.web.loj` through:
|
|
12
|
+
|
|
13
|
+
- `readModel <name> rules: '@rules("./rules/x")'`
|
|
14
|
+
- `resource create.rules: '@rules("./rules/x")'`
|
|
15
|
+
- `resource edit.rules: '@rules("./rules/x")'`
|
|
16
|
+
- `resource create.includes[].rules: '@rules("./rules/x")'`
|
|
17
|
+
- `resource edit.includes[].rules: '@rules("./rules/x")'`
|
|
18
|
+
|
|
19
|
+
It is still not orchestrated through `loj.project.yaml`.
|
|
20
|
+
|
|
21
|
+
## Current Scope
|
|
22
|
+
|
|
23
|
+
Implemented today:
|
|
24
|
+
|
|
25
|
+
- `.rules.loj` file suffix
|
|
26
|
+
- one named rule set per file
|
|
27
|
+
- parser + validator + target-neutral semantic manifest generation
|
|
28
|
+
- grouped rule entry kinds:
|
|
29
|
+
- `allow/deny <operation>`
|
|
30
|
+
- `eligibility <name>`
|
|
31
|
+
- `validate <name>`
|
|
32
|
+
- `derive <field>`
|
|
33
|
+
- repo CLI entry:
|
|
34
|
+
- `loj rules validate <file.rules.loj>`
|
|
35
|
+
- `loj rules build <file.rules.loj> --out-dir <dir>`
|
|
36
|
+
|
|
37
|
+
Not implemented yet:
|
|
38
|
+
|
|
39
|
+
- workflow `.flow.loj`
|
|
40
|
+
- project-shell orchestration for rules targets
|
|
41
|
+
- broader frontend `.rules.loj` consumers beyond the current read-model plus generated create/edit form surfaces
|
|
42
|
+
|
|
43
|
+
## File Shape
|
|
44
|
+
|
|
45
|
+
Use one top-level block:
|
|
46
|
+
|
|
47
|
+
```yaml
|
|
48
|
+
rules invoice-access:
|
|
49
|
+
allow list:
|
|
50
|
+
when: currentUser.role in [ADMIN, FINANCE, SALES]
|
|
51
|
+
|
|
52
|
+
allow update:
|
|
53
|
+
when: currentUser.role == ADMIN
|
|
54
|
+
or:
|
|
55
|
+
- currentUser.id == record.accountManagerId
|
|
56
|
+
|
|
57
|
+
deny delete:
|
|
58
|
+
when: record.status == COMPLETED
|
|
59
|
+
message:
|
|
60
|
+
key: "invoice.delete.completed"
|
|
61
|
+
defaultMessage: "Completed invoices cannot be deleted."
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Rules:
|
|
65
|
+
|
|
66
|
+
- exactly one top-level `rules <name>:` block per file
|
|
67
|
+
- entry keys may be:
|
|
68
|
+
- `allow <operation>`
|
|
69
|
+
- `deny <operation>`
|
|
70
|
+
- `eligibility <name>`
|
|
71
|
+
- `validate <name>`
|
|
72
|
+
- `derive <field>`
|
|
73
|
+
- supported operations:
|
|
74
|
+
- `list`
|
|
75
|
+
- `get`
|
|
76
|
+
- `create`
|
|
77
|
+
- `update`
|
|
78
|
+
- `delete`
|
|
79
|
+
|
|
80
|
+
## Supported Fields
|
|
81
|
+
|
|
82
|
+
Inside auth `allow ...` / `deny ...` blocks:
|
|
83
|
+
|
|
84
|
+
- required:
|
|
85
|
+
- `when`
|
|
86
|
+
- optional:
|
|
87
|
+
- `or`
|
|
88
|
+
- `message`
|
|
89
|
+
- `scopeWhen`
|
|
90
|
+
- `scope`
|
|
91
|
+
|
|
92
|
+
Field rules:
|
|
93
|
+
|
|
94
|
+
- `when` must be a non-empty expression string
|
|
95
|
+
- `or` may be one string or a sequence of strings
|
|
96
|
+
- `message` may be:
|
|
97
|
+
- one string
|
|
98
|
+
- one descriptor object with `key`, `defaultMessage`, optional `values`
|
|
99
|
+
- `scopeWhen` and `scope` are allowed only on `list`
|
|
100
|
+
- if one of `scopeWhen` / `scope` is present, both must be present
|
|
101
|
+
|
|
102
|
+
Inside `eligibility <name>` / `validate <name>` blocks:
|
|
103
|
+
|
|
104
|
+
- required:
|
|
105
|
+
- `when`
|
|
106
|
+
- optional:
|
|
107
|
+
- `or`
|
|
108
|
+
- `message`
|
|
109
|
+
|
|
110
|
+
Inside `derive <field>` blocks:
|
|
111
|
+
|
|
112
|
+
- required:
|
|
113
|
+
- `value`
|
|
114
|
+
- optional:
|
|
115
|
+
- `when`
|
|
116
|
+
|
|
117
|
+
## Expression Language
|
|
118
|
+
|
|
119
|
+
The current rules proof reuses the same constrained expression language used by core web-family
|
|
120
|
+
rules.
|
|
121
|
+
|
|
122
|
+
Use:
|
|
123
|
+
|
|
124
|
+
- comparisons like `==`, `!=`, `>`, `<`, `>=`, `<=`
|
|
125
|
+
- arithmetic like `+`, `-`, `*`, `/`
|
|
126
|
+
- logical `&&`, `||`, `not`
|
|
127
|
+
- dotted paths like `currentUser.role`, `record.status`
|
|
128
|
+
- membership like `currentUser.role in [ADMIN, SALES]`
|
|
129
|
+
- built-ins such as `hasRole(...)`, `isOwner(...)`, `isEmpty(...)`, `count(...)`
|
|
130
|
+
|
|
131
|
+
Do not use:
|
|
132
|
+
|
|
133
|
+
- raw JavaScript or Python
|
|
134
|
+
- statements, loops, imports, closures
|
|
135
|
+
- framework/runtime internals
|
|
136
|
+
|
|
137
|
+
## Current Command Path
|
|
138
|
+
|
|
139
|
+
Validate:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
loj rules validate ./policies/invoice-access.rules.loj
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Build manifest:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
loj rules build ./policies/invoice-access.rules.loj --out-dir ./generated/rules
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Current build output is a standalone semantic manifest JSON file. Treat it as the first proof
|
|
152
|
+
surface plus a few narrow backend-family linkage points, not as a finished cross-target rules
|
|
153
|
+
system.
|
|
154
|
+
|
|
155
|
+
## Hard Guardrails
|
|
156
|
+
|
|
157
|
+
- The only implemented `.api.loj` linkages are:
|
|
158
|
+
- `resource auth.policy: '@rules("./policies/x")'`
|
|
159
|
+
- `resource create.rules: '@rules("./rules/x")'`
|
|
160
|
+
- `readModel <name> rules: '@rules("./rules/x")'`
|
|
161
|
+
- The implemented `.web.loj` linkages are:
|
|
162
|
+
- `readModel <name> rules: '@rules("./rules/x")'`
|
|
163
|
+
- `resource create.rules: '@rules("./rules/x")'`
|
|
164
|
+
- `resource edit.rules: '@rules("./rules/x")'`
|
|
165
|
+
- `resource create.includes[].rules: '@rules("./rules/x")'`
|
|
166
|
+
- `resource edit.includes[].rules: '@rules("./rules/x")'`
|
|
167
|
+
- Current linkage boundaries:
|
|
168
|
+
- `auth.policy` consumes only `allow/deny` auth entries
|
|
169
|
+
- backend `create.rules` consumes only `eligibility` + `validate`
|
|
170
|
+
- `readModel rules` consumes only `eligibility` + `validate` + `derive`
|
|
171
|
+
- frontend `readModel rules` use `eligibility` / `validate` only for local fetch gating and `derive` only for client-side row derivation after fetch
|
|
172
|
+
- frontend `create.rules` / `edit.rules` use `eligibility` for local generated-form gating, `validate` for local pre-submit checks, and `derive` only for top-level scalar generated fields already listed in the form
|
|
173
|
+
- frontend `create.includes[].rules` / `edit.includes[].rules` use `eligibility` / `validate` for local repeated-child item gating and validation, and `derive` only for scalar child fields already listed in that include's `fields:`
|
|
174
|
+
- frontend `readModel rules` reject `allow/deny` entries
|
|
175
|
+
- frontend generated form consumers (`create.rules`, `edit.rules`, `create.includes[].rules`, `edit.includes[].rules`) all reject `allow/deny` entries
|
|
176
|
+
- Do not invent `type: rules` inside `loj.project.yaml` yet.
|
|
177
|
+
- Do not add workflow/state-machine syntax to `.rules.loj`.
|
|
178
|
+
- Keep rule authoring declarative and target-neutral.
|