prisma-php 0.0.6 → 0.0.8

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.
@@ -7,15 +7,16 @@
7
7
 
8
8
  ## Route File Conventions
9
9
 
10
- - For PulsePoint-aware `index.php` and `layout.php`, keep file order as PHP, then HTML, then one `<script>` block.
10
+ - For PulsePoint-aware `index.php` and nested `layout.php`, keep file order as PHP first, then one parent HTML element; keep the PulsePoint `<script>` as the last child inside that same root element.
11
11
  - `index.php` and nested `layout.php` must render a single parent HTML element. Treat that root like a React-style component boundary rather than loose sibling markup.
12
- - Only the root `layout.php` should define `<html>`, `<head>`, and `<body>`. When PulsePoint is present, keep `MainLayout::$children;` inside one clear wrapper.
12
+ - When a route or nested layout uses PulsePoint, put `pp-component` on that single root element and keep any route-local `<script>` inside it.
13
+ - Only the root `layout.php` should define `<html>`, `<head>`, and `<body>`. When PulsePoint is present, keep `MainLayout::$children;` and any `<script>` inside one clear wrapper.
13
14
 
14
15
  ## Component Boundary Rules
15
16
 
16
17
  - Distinguish PHPX class components from `ImportComponent` partials.
17
18
  - `ImportComponent` partials must output exactly one root element because Prisma PHP attaches serialized props and a stable `pp-component` attribute to that root.
18
- - Do not manually add `pp-component` unless a documented framework feature injects it for that boundary.
19
+ - Do not manually add `pp-component` inside `ImportComponent` partial source; Prisma PHP injects it there. For normal PulsePoint-aware route files, add `pp-component` to the single root element yourself.
19
20
 
20
21
  ## Relevant Docs
21
22
 
@@ -86,7 +86,7 @@ For a normal route file such as `src/app/index.php` or nested `layout.php`, use
86
86
 
87
87
  1. PHP
88
88
  2. one parent HTML element for the route content
89
- 3. one `<script>` block after that parent element
89
+ 3. when PulsePoint is present, keep one `<script>` block as the last child inside that same root element
90
90
 
91
91
  Example route-file pattern:
92
92
 
@@ -96,14 +96,13 @@ Example route-file pattern:
96
96
  $title = 'Dashboard';
97
97
  ?>
98
98
 
99
- <section class="dashboard-page">
99
+ <section pp-component="dashboard-page">
100
100
  <h1><?= htmlspecialchars($title) ?></h1>
101
101
  <p>Count: {count}</p>
102
+ <script>
103
+ const [count, setCount] = pp.state(0);
104
+ </script>
102
105
  </section>
103
-
104
- <script>
105
- const [count, setCount] = pp.state(0);
106
- </script>
107
106
  ```
108
107
 
109
108
  That is the correct route-page pattern. It is documented in `layouts-and-pages.md`, not in `ImportComponent`.
@@ -117,11 +116,11 @@ Correct imported-partial pattern:
117
116
  ```php filename="src/app/inc/SearchBox.php"
118
117
  <?php
119
118
 
120
- $title = 'Search';
119
+ // PHP Code
121
120
  ?>
122
121
 
123
- <div class="rounded-lg border bg-card p-4" pp-component="search-box">
124
- <h2 class="font-medium"><?= htmlspecialchars($title) ?></h2>
122
+ <div class="rounded-lg border bg-card p-4">
123
+ <h2 class="font-medium">Search</h2>
125
124
  <input value="{query}" oninput="{(e) => setQuery(e.target.value)}" />
126
125
  <script>
127
126
  console.log('Search component ready');
@@ -134,11 +133,11 @@ Incorrect imported-partial pattern:
134
133
  ```php filename="src/app/inc/SearchBox.php"
135
134
  <?php
136
135
 
137
- $title = 'Search';
136
+ // PHP Code
138
137
  ?>
139
138
 
140
139
  <section class="rounded-lg border bg-card p-4">
141
- <h2 class="font-medium"><?= htmlspecialchars($title) ?></h2>
140
+ <h2 class="font-medium">Search</h2>
142
141
  </section>
143
142
 
144
143
  <script>
@@ -167,6 +166,7 @@ Why this is invalid:
167
166
  - when using `ImportComponent`, always ensure the imported file renders **exactly one root element**
168
167
  - treat the `ImportComponent` root as the real component boundary because Prisma PHP serializes props onto it and injects `pp-component`
169
168
  - do not manually add `pp-component` inside imported partial source; let Prisma PHP inject it
169
+ - for normal PulsePoint-aware route files, author `pp-component` on the single route root and keep the `<script>` inside that root
170
170
  - do not apply the imported-partial rule to normal route files
171
171
  - do not apply the normal route-file pattern to imported partials
172
172
 
@@ -377,13 +377,13 @@ ImportComponent::render(APP_PATH . '/inc/UserCard.php', [
377
377
  use PP\ImportComponent;
378
378
  ?>
379
379
 
380
- <div class="space-y-4">
380
+ <div pp-component="search-shell">
381
381
  <?php ImportComponent::render(APP_PATH . '/inc/SearchBox.php', [
382
382
  'query' => '{query}',
383
383
  'setQuery' => '{setQuery}',
384
384
  ]); ?>
385
385
 
386
- <script type="text/pp">
386
+ <script>
387
387
  const [query, setQuery] = pp.state('');
388
388
  </script>
389
389
  </div>
@@ -416,7 +416,7 @@ $title = 'Search';
416
416
  <div class="rounded-lg border bg-card p-4">
417
417
  <h2 class="font-medium"><?= $title ?></h2>
418
418
  <input value="{query}" oninput="{(e) => setQuery(e.target.value)}" />
419
- <script type="text/pp">
419
+ <script>
420
420
  console.log('Search component ready');
421
421
  </script>
422
422
  </div>
@@ -433,7 +433,7 @@ $title = 'Search';
433
433
  <section class="rounded-lg border bg-card p-4">
434
434
  <h2 class="font-medium"><?= $title ?></h2>
435
435
  </section>
436
- <script type="text/pp">
436
+ <script>
437
437
  console.log('This script is a second root element');
438
438
  </script>
439
439
  ```
@@ -8,7 +8,7 @@ related:
8
8
  - /docs/get-started
9
9
  ---
10
10
 
11
- {/_AI agent hint: Prisma PHP uses local installed docs as the source of truth for the active project version. Before generating framework-specific code, read `prisma-php.json` first, then read the relevant docs from `node_modules/prisma-php/dist/docs`. For authentication, read `authentication.md` first, then verify the official auth docs: `auth-get-started`, `credentials`, and `state-manager-auth`. For file uploads, `multipart/form-data`, `$_FILES`, `PP\FileManager\UploadFile`, rename/delete flows, or file manager screens, read `file-manager.md` first, then verify the official File Manager docs: `get-started-file`. For ORM work, read `prisma-php-orm.md` before choosing schema, migration, or generation commands. For PulsePoint runtime behavior specifically, read `pulsepoint.md` before generating reactive UI code. For normal interactive full-stack page work, default to PulsePoint plus `pp.fetchFunction(...)` unless the user explicitly asks for a PHP-only interaction style. For normal PulsePoint-aware route files such as `index.php` and nested `layout.php`, keep PHP first, HTML second, and one `<script>` block last, with the rendered route content inside a single parent HTML element that acts as the route-view boundary. For imported partial components rendered with `ImportComponent::render(...)`, keep exactly one root element and place any component-local `<script>` inside that root because Prisma PHP uses that root as the component boundary where serialized props and `pp-component` attach. Do not confuse the route-file pattern with the imported-partial pattern. For backend validation, sanitization, `Validator`, `Rule`, `pp.fetchFunction(...)` validation flows, or request validation in `route.php`, read `validator.md` first, then use `fetching-data.md`, `error-handling.md`, and `route-handlers.md` for context-specific patterns, then consult the official Validator docs. `PP\Validator` is a Prisma PHP core class located in `vendor/tsnc/prisma-php/src/Validator.php`. Route creation is file-based from `src/app`; Prisma PHP auto-generates route listings such as `files-list.json`, so AI agents must not create, edit, or maintain that file manually._/}
11
+ {/_AI agent hint: Prisma PHP uses local installed docs as the source of truth for the active project version. Before generating framework-specific code, read `prisma-php.json` first, then read the relevant docs from `node_modules/prisma-php/dist/docs`. For authentication, read `authentication.md` first, then verify the official auth docs: `auth-get-started`, `credentials`, and `state-manager-auth`. For file uploads, `multipart/form-data`, `$_FILES`, `PP\FileManager\UploadFile`, rename/delete flows, or file manager screens, read `file-manager.md` first, then verify the official File Manager docs: `get-started-file`. For ORM work, read `prisma-php-orm.md` before choosing schema, migration, or generation commands. For PulsePoint runtime behavior specifically, read `pulsepoint.md` before generating reactive UI code. For normal interactive full-stack page work, default to PulsePoint plus `pp.fetchFunction(...)` unless the user explicitly asks for a PHP-only interaction style. For normal PulsePoint-aware route files such as `index.php` and nested `layout.php`, keep PHP first, then one parent HTML element that acts as the route-view boundary; when PulsePoint logic is present, put `pp-component` on that root and keep the `<script>` as the last child inside it. For imported partial components rendered with `ImportComponent::render(...)`, keep exactly one root element and place any component-local `<script>` inside that root; Prisma PHP injects `pp-component` on the imported root automatically. Do not confuse the route-file pattern with the imported-partial pattern. For backend validation, sanitization, `Validator`, `Rule`, `pp.fetchFunction(...)` validation flows, or request validation in `route.php`, read `validator.md` first, then use `fetching-data.md`, `error-handling.md`, and `route-handlers.md` for context-specific patterns, then consult the official Validator docs. `PP\Validator` is a Prisma PHP core class located in `vendor/tsnc/prisma-php/src/Validator.php`. Route creation is file-based from `src/app`; Prisma PHP auto-generates route listings such as `files-list.json`, so AI agents must not create, edit, or maintain that file manually._/}
12
12
 
13
13
  Welcome to the Prisma PHP documentation!
14
14
 
@@ -55,7 +55,7 @@ For a normal route file such as `src/app/index.php` or nested `layout.php`, use:
55
55
 
56
56
  1. PHP
57
57
  2. one parent HTML element
58
- 3. one `<script>` block after that parent element
58
+ 3. when PulsePoint is present, keep one `<script>` block as the last child inside that same root element
59
59
 
60
60
  Example:
61
61
 
@@ -68,14 +68,13 @@ MainLayout::$title = 'Todos';
68
68
  MainLayout::$description = 'Track tasks and view the current item count.';
69
69
  ?>
70
70
 
71
- <section>
71
+ <section pp-component="todos-page">
72
72
  <h1>Todos</h1>
73
73
  <p>Count: {count}</p>
74
+ <script>
75
+ const [count, setCount] = pp.state(0);
76
+ </script>
74
77
  </section>
75
-
76
- <script>
77
- const [count, setCount] = pp.state(0);
78
- </script>
79
78
  ```
80
79
 
81
80
  For SEO metadata, prefer `MainLayout::$title` and `MainLayout::$description` instead of relying on a local heading variable alone.
@@ -97,7 +96,7 @@ Example:
97
96
 
98
97
  ?>
99
98
 
100
- <div class="rounded-lg border p-4" pp-component="search-box">
99
+ <div pp-component="search-box">
101
100
  <h2>Search</h2>
102
101
  <input value="{query}" />
103
102
  <script>
@@ -134,9 +133,10 @@ Do not confuse the route-file pattern with the `ImportComponent` partial pattern
134
133
  - create routes by adding folders and route files under `src/app`
135
134
  - do not create, edit, or maintain `files-list.json`; Prisma PHP generates route listings automatically
136
135
  - when building interactive frontend behavior, prefer the documented PulsePoint pattern with browser-side reactive state and `pp.fetchFunction(...)` for server calls; treat this as the default unless the user explicitly asks for a PHP-only interaction pattern
137
- - when building PulsePoint inside `index.php` or `layout.php`, read `layouts-and-pages.md` together with `pulsepoint.md`, use PHP then HTML then one `<script>` block, keep route content inside a single parent HTML element, and treat that root as the route-view boundary
138
- - when importing a PHP partial with `ImportComponent`, require exactly one root element and keep any partial-local `<script>` inside that root because Prisma PHP attaches serialized props and a stable `pp-component` attribute to that root
139
- - do not manually sprinkle `pp-component` across normal route markup
136
+ - when building PulsePoint inside `index.php` or `layout.php`, read `layouts-and-pages.md` together with `pulsepoint.md`, use one parent route root, put `pp-component` on that root, and keep the `<script>` inside it as the last child
137
+ - when importing a PHP partial with `ImportComponent`, require exactly one root element and keep any partial-local `<script>` inside that root because Prisma PHP attaches serialized props and a stable `pp-component` attribute to that imported root
138
+ - do not leave a PulsePoint `<script>` as a sibling outside the route root
139
+ - do not manually add `pp-component` inside imported partial source; Prisma PHP injects it there
140
140
  - when building backend validation logic, read `validator.md` first, then use the route-specific docs for the request entry point
141
141
  - when using `pp.fetchFunction(...)`, expose the PHP function explicitly with `#[Exposed]`
142
142
  - when changing feature flags, update `prisma-php.json` first, then follow the documented update workflow
@@ -61,20 +61,21 @@ Only shift to a more PHP-only pattern when the user explicitly asks for it or wh
61
61
  When `index.php` or `layout.php` includes PulsePoint, keep the file in this order:
62
62
 
63
63
  1. PHP
64
- 2. HTML
65
- 3. SCRIPT
64
+ 2. one parent HTML element
65
+ 3. keep the PulsePoint `<script>` as the last child inside that root element
66
66
 
67
67
  In practice, that means:
68
68
 
69
69
  - put imports, server-side queries, request access, helper functions, and exposed PHP functions in the top PHP block
70
- - render the route markup after the PHP block
71
- - place one PulsePoint `<script>` block at the bottom of the file
70
+ - render the route markup inside one parent element after the PHP block
71
+ - when PulsePoint is present, put `pp-component` on that single route or layout root
72
+ - place one PulsePoint `<script>` block at the bottom of that same root element
72
73
 
73
74
  For the HTML portion, keep a **single parent HTML tag** around the route content. Treat that root as the page or layout boundary instead of as a throwaway wrapper.
74
75
 
75
76
  - In `index.php`, wrap the page UI in one parent element such as `<main>`, `<section>`, or `<article>`, and treat that root as the route-view boundary.
76
77
  - In nested `layout.php`, wrap the shared layout UI and `<?= MainLayout::$children; ?>` in one parent element so the layout still behaves like one boundary.
77
- - The root `layout.php` is the document shell and is the only layout that should contain `<html>` and `<body>`. Inside `<body>`, keep one clear wrapper around `<?= MainLayout::$children; ?>` when PulsePoint behavior is present.
78
+ - The root `layout.php` is the document shell and is the only layout that should contain `<html>` and `<body>`. Inside `<body>`, keep one clear wrapper around `<?= MainLayout::$children; ?>`, and keep any PulsePoint `<script>` inside that same wrapper when PulsePoint behavior is present.
78
79
 
79
80
  ### Important distinction: route files vs imported partials
80
81
 
@@ -84,7 +85,7 @@ For **normal route files** such as `src/app/index.php` and nested `layout.php`,
84
85
 
85
86
  1. PHP
86
87
  2. one parent HTML element for the rendered route UI
87
- 3. one `<script>` block after that parent element
88
+ 3. when PulsePoint is present, keep one `<script>` block as the last child inside that same root element
88
89
 
89
90
  Correct route-file pattern:
90
91
 
@@ -99,20 +100,19 @@ MainLayout::$title = 'Todos';
99
100
  MainLayout::$description = 'Track tasks and view the current item count.';
100
101
  ?>
101
102
 
102
- <section class="space-y-4">
103
+ <section pp-component="todos-page">
103
104
  <h1>Todos</h1>
104
105
  <p>Count: {count}</p>
106
+ <script>
107
+ const [count, setCount] = pp.state(0);
108
+ </script>
105
109
  </section>
106
-
107
- <script>
108
- const [count, setCount] = pp.state(0);
109
- </script>
110
110
  ```
111
111
 
112
112
  That is the default structure for a PulsePoint-aware route page.
113
113
  Use `MainLayout::$title` and `MainLayout::$description` for page metadata, and keep a separate heading variable only when the visible heading text needs to differ.
114
114
 
115
- By contrast, **imported partials rendered with `ImportComponent::render(...)` follow a different rule**: the imported file must emit exactly **one root element**, and if it contains a `<script>`, that script must live **inside** that root element. Read `components.md` for that pattern.
115
+ By contrast, **imported partials rendered with `ImportComponent::render(...)` keep the same single-root requirement but a different `pp-component` responsibility**: the imported file must emit exactly **one root element**, any component-local `<script>` must live **inside** that root element, and Prisma PHP injects `pp-component` on that imported root automatically. Read `components.md` for that pattern.
116
116
 
117
117
  ## Creating a page
118
118
 
@@ -167,7 +167,7 @@ use PP\MainLayout;
167
167
  ```
168
168
 
169
169
  The root layout is defined at the top level of your app directory and wraps the content for the entire application.
170
- If this root layout uses PulsePoint, keep the same file order: PHP first, then the document HTML, then a single `<script>` block near the end of `<body>`.
170
+ If this root layout uses PulsePoint, keep the same file order: PHP first, then the document HTML, and keep any route-local `<script>` inside a single wrapper near the end of `<body>`.
171
171
 
172
172
  ## Creating a nested route
173
173
 
@@ -385,10 +385,10 @@ echo json_encode($users);
385
385
  - If a user asks for an API route or direct handler, prefer `route.php`.
386
386
  - The root layout is required and should contain the global HTML document structure.
387
387
  - Only the root layout should contain `<html>` and `<body>` tags.
388
- - When `index.php` or `layout.php` uses PulsePoint, structure the file as PHP, then HTML, then one `<script>` block.
388
+ - When `index.php` or `layout.php` uses PulsePoint, structure the file as PHP first, then one root HTML element, and keep the `<script>` inside that root as its last child.
389
389
  - `index.php` and nested `layout.php` should render one parent HTML element; only the root layout should contain `<html>` and `<body>`.
390
390
  - Layouts can be nested by placing `layout.php` files inside route folders.
391
391
  - Dynamic route parameters are available through `Request::$dynamicParams`.
392
392
  - Route groups let you organize routes and assign different layouts without affecting the URL.
393
393
  - Private folders help you colocate implementation files without making them routable.
394
- - Imported partials rendered through `ImportComponent` follow a different structural rule: one root element containing any component-local `<script>`.
394
+ - Imported partials rendered through `ImportComponent` follow the same single-root rule but a different boundary rule: keep the component-local `<script>` inside that root and let Prisma PHP inject `pp-component` there.
@@ -193,13 +193,23 @@ Use this flow:
193
193
  3. confirm that `DATABASE_URL` exists
194
194
  4. resolve the SQLite file path from `DATABASE_URL`
195
195
  5. confirm the path is valid for the project
196
- 6. if the SQLite database file is missing, invalid, or not initialized yet, run:
196
+ 6. when the user is using SQLite, prefer saving the database file inside the local `./prisma` directory
197
+ 7. for the normal local setup, use:
198
+
199
+ ```env
200
+ DATABASE_URL="file:./prisma/dev.db"
201
+ ```
202
+
203
+ 8. confirm the resolved path points to a valid project-local SQLite file such as `./prisma/dev.db`
204
+ 9. do not point the SQLite file at an unrelated root-level location when the project is using the standard Prisma PHP layout
205
+ 10. if the `./prisma` directory is the intended storage location, the SQLite database file should be created and saved there
206
+ 11. if the SQLite database file is missing, invalid, or not initialized yet, run:
197
207
 
198
208
  ```bash
199
209
  npx prisma migrate dev
200
210
  ```
201
211
 
202
- 7. after migration succeeds, run:
212
+ 12. after migration succeeds, run:
203
213
 
204
214
  ```bash
205
215
  npx ppo generate
@@ -209,6 +219,7 @@ Important SQLite rule:
209
219
 
210
220
  - if Prisma PHP reports that the SQLite database file was not found or could not be created, AI must not stop at `npx ppo generate`
211
221
  - in that situation, the database initialization or migration step is still required
222
+ - when `.env` uses `DATABASE_URL="file:./prisma/dev.db"`, treat `./prisma` as the expected directory for the SQLite database file
212
223
 
213
224
  ## MySQL and PostgreSQL workflow
214
225
 
@@ -114,7 +114,7 @@ For normal PulsePoint-aware route files, use:
114
114
 
115
115
  1. PHP
116
116
  2. one parent HTML element
117
- 3. one `<script>` block after that parent element
117
+ 3. when PulsePoint is present, keep one `<script>` block as the last child inside that same root element
118
118
 
119
119
  Example:
120
120
 
@@ -127,14 +127,13 @@ MainLayout::$title = 'Dashboard';
127
127
  MainLayout::$description = 'View dashboard metrics and current activity.';
128
128
  ?>
129
129
 
130
- <section class="dashboard-page">
130
+ <section pp-component="dashboard-page">
131
131
  <h1>Dashboard</h1>
132
132
  <p>Count: {count}</p>
133
+ <script>
134
+ const [count, setCount] = pp.state(0);
135
+ </script>
133
136
  </section>
134
-
135
- <script>
136
- const [count, setCount] = pp.state(0);
137
- </script>
138
137
  ```
139
138
 
140
139
  That is the default route-file structure for a full-stack page.
@@ -144,18 +143,18 @@ For document metadata, set `MainLayout::$title` and `MainLayout::$description` i
144
143
 
145
144
  An imported partial rendered through `ImportComponent::render(...)` is **not** a normal route file.
146
145
 
147
- For imported partials, the file must emit exactly **one root element**, and if the partial contains a `<script>`, that script must live **inside** that root element.
146
+ For imported partials, the file must emit exactly **one root element**, and if the partial contains a `<script>`, that script must live **inside** that root element. Prisma PHP injects `pp-component` for that imported boundary automatically.
148
147
 
149
148
  Example:
150
149
 
151
150
  ```php filename="src/app/inc/SearchBox.php"
152
151
  <?php
153
152
 
154
- $title = 'Search';
153
+ // PHP Code
155
154
  ?>
156
155
 
157
- <div class="rounded-lg border p-4" pp-component="search-box">
158
- <h2><?= htmlspecialchars($title) ?></h2>
156
+ <div pp-component="search-box">
157
+ <h2>Search</h2>
159
158
  <input value="{query}" />
160
159
  <script>
161
160
  console.log('Search component ready');
@@ -15,6 +15,7 @@ A component root is any element with `pp-component`.
15
15
  ## Component roots and scripts
16
16
 
17
17
  - Each component root may contain one inline `<script>` block for component logic.
18
+ - Keep that `<script>` inside the same `pp-component` root. Do not leave it as a sibling after the root element.
18
19
  - The script is plain JavaScript, not a module. Do not use `import` or `export` inside it.
19
20
  - Top-level bindings from the script are exported automatically to the template. Do not manually `return { ... }`.
20
21
  - Top-level `const`, `let`, `function`, and supported destructuring patterns become template bindings.
@@ -191,7 +192,7 @@ Do not generate these unless the current source explicitly supports them:
191
192
  - `pp-dynamic-script`
192
193
  - `pp-dynamic-meta`
193
194
  - `pp-dynamic-link`
194
- - plain `<script>` for component logic inside a component root
195
+ - component logic `<script>` blocks outside a `pp-component` root
195
196
  - React, Vue, Svelte, or JSX-style component patterns that are not implemented here
196
197
  - made-up hooks, directives, or globals not present in the current TypeScript source
197
198
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prisma-php",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Prisma PHP tooling",
5
5
  "main": "index.js",
6
6
  "scripts": {