@prisma/security-rules 0.0.0-dev.202504071300
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 +212 -0
- package/assets/operation-rules.png +0 -0
- package/assets/rpc.png +0 -0
- package/assets/rule-engine.png +0 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +126 -0
- package/dist/index.d.ts +126 -0
- package/dist/index.js +1 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# @prisma/security-rules
|
|
2
|
+
|
|
3
|
+
## Permission rules for Prisma Postgres
|
|
4
|
+
|
|
5
|
+
Prisma Security Rules is a **permission rules system for Prisma ORM and Prisma Postgres**. With Security Rules, you can:
|
|
6
|
+
|
|
7
|
+
- Define access permission rules in TypeScript
|
|
8
|
+
- Deploy the permission rules to your Prisma Postgres instance
|
|
9
|
+
- Query Prisma Postgres with the permission rules applied
|
|
10
|
+
- Access Prisma Postgres from the frontend
|
|
11
|
+
|
|
12
|
+
At the core of it, you define rules that allow/deny requests to your database based on model name, operation (e.g. `findMany`) and the parameters you pass to said operation.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
### Prerequisites
|
|
17
|
+
|
|
18
|
+
- A project with Prisma ORM (>=6.2.0) installed and a Prisma Postgres database. If you don’t have one, you can get started [here](https://www.prisma.io/docs/getting-started/prisma-postgres/from-the-cli?utm_source=readme&utm_medium=security_rules).
|
|
19
|
+
|
|
20
|
+
- The Prisma CLI being authenticated with Prisma Data Platform (via [`prisma platform auth login --early-access`](https://www.prisma.io/docs/platform/platform-cli/commands?utm_source=readme&utm_medium=security_rules#auth-login)).
|
|
21
|
+
|
|
22
|
+
### 1. Install the Security Rules package
|
|
23
|
+
|
|
24
|
+
```shell
|
|
25
|
+
npm install @prisma/security-rules
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
<details>
|
|
29
|
+
<summary>
|
|
30
|
+
Expand to see installation instructions for `pnpm`, `yarn` and `bun`
|
|
31
|
+
</summary>
|
|
32
|
+
|
|
33
|
+
#### pnpm
|
|
34
|
+
|
|
35
|
+
```shell
|
|
36
|
+
pnpm add @prisma/security-rules
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
#### Yarn
|
|
40
|
+
|
|
41
|
+
```shell
|
|
42
|
+
yarn add @prisma/security-rules
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
#### Bun
|
|
46
|
+
|
|
47
|
+
```shell
|
|
48
|
+
bun install @prisma/security-rules
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
</details>
|
|
52
|
+
|
|
53
|
+
### 2. Define your Security Rules
|
|
54
|
+
|
|
55
|
+
First, import the package and define your rules. Create a `rules.ts`in your `prisma` folder:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { PrismaClient } from "@prisma/client";
|
|
59
|
+
import { defineRules } from "@prisma/security-rules";
|
|
60
|
+
import { z } from "zod";
|
|
61
|
+
|
|
62
|
+
import { decode } from "path/to/decode"; // imaginary import of your jwt token decode helper
|
|
63
|
+
|
|
64
|
+
export default defineRules({
|
|
65
|
+
prisma: new PrismaClient(),
|
|
66
|
+
contextSchema: z.object({
|
|
67
|
+
token: z.string(),
|
|
68
|
+
}),
|
|
69
|
+
rules: {
|
|
70
|
+
user: {
|
|
71
|
+
async read(req) {
|
|
72
|
+
// On each request, the context object can be used to perform custom auth/access business logic. We know it's shape thanks to the `contextSchema` property.
|
|
73
|
+
const { userId } = await decode(req.context.token);
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
$where: { id: userId },
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
$allOperations: false,
|
|
80
|
+
},
|
|
81
|
+
$allModels: false,
|
|
82
|
+
$transaction: false,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
> Note: While the rules are applied to your `PrismaClient` instance, this instance will retain _full_ database access.
|
|
88
|
+
|
|
89
|
+
This example uses `zod`, but you can use any schema library that implements the [standard schema](https://github.com/standard-schema/standard-schema#what-schema-libraries-implement-the-spec) specification.
|
|
90
|
+
|
|
91
|
+
This example includes rules that will deny all requests except for reads (e.g. `findMany`) on `user` model. It also ensures a user only sees their own data by applying a `where` override (effectively `AND(incoming_query_where, rule_$where)`) that filters by the user's id (decoded from the session token).
|
|
92
|
+
|
|
93
|
+
### 3. Deploy your Security Rules
|
|
94
|
+
|
|
95
|
+
```shell
|
|
96
|
+
prisma rules deploy <rules_name> -f ./prisma/rules.ts
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Be sure to copy the public key from the deploy command's output in your terminal, and replace the `<public_key>` below.
|
|
100
|
+
|
|
101
|
+
### 4. Use `AuthorizedClient` to access Prisma Postgres
|
|
102
|
+
|
|
103
|
+
`AuthorizedClient` is a lightweight version of `PrismaClient` that you can use in your browser. Once your rules are deployed, you can use it as follows in your application:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { AuthorizedClient } from "@prisma/security-rules";
|
|
107
|
+
|
|
108
|
+
// It is important not to forget the `type` annotation here.
|
|
109
|
+
import type rules from "path/to/prisma/rules";
|
|
110
|
+
|
|
111
|
+
const authorizedClient = new AuthorizedClient<typeof rules>({
|
|
112
|
+
publicKey: "<public_key>",
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
prisma.setGlobalContext({ token: "<some_session_token>" });
|
|
116
|
+
|
|
117
|
+
const users = await prisma.users.findMany();
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## How it works
|
|
121
|
+
|
|
122
|
+
This package exposes:
|
|
123
|
+
|
|
124
|
+
- A `defineRules` helper to attach Prisma Security Rules to an existing Prisma ORM client, which gets deployed at the edge when you run `prisma rules deploy`.
|
|
125
|
+
|
|
126
|
+
- An `AuthorizedClient` class that is a drop-in replacement for `PrismaClient`, a lightweight client that will enforce the rules you've defined and deployed.
|
|
127
|
+
|
|
128
|
+
Here's a simplified high-level view of Prisma Security Rule's architecture:
|
|
129
|
+
|
|
130
|
+

|
|
131
|
+
|
|
132
|
+
### Rule Engine
|
|
133
|
+
|
|
134
|
+
Each request, that is received by Prisma Security Rules' workers, will be evaluated by a rule engine:
|
|
135
|
+
|
|
136
|
+
- If a request does not adhere to your rules, it will be denied with a reason, and the `AuthorizedClient` will throw an error.
|
|
137
|
+
- If a request adheres to your rules, it will be executed with the `PrismaClient` and the results will be sent to the `AuthorizedClient`.
|
|
138
|
+
|
|
139
|
+
#### Rules
|
|
140
|
+
|
|
141
|
+
Rules are defined with a JavaScript plain nested object.
|
|
142
|
+
|
|
143
|
+
The root object is defined as:
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
{
|
|
147
|
+
// model name must exist in your `PrismaClient`'s schema.
|
|
148
|
+
// when your schema changes, make sure to redeploy your rules,
|
|
149
|
+
// to avoid instant denies from the engine for requests that access new models.
|
|
150
|
+
[modelName: string]?: ModelRules;
|
|
151
|
+
// fallback in case the request's model name has no specific rules.
|
|
152
|
+
$allModels?: ModelRules;
|
|
153
|
+
// allow or deny transactions.
|
|
154
|
+
$transaction?: boolean;
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Model rules are defined as follows:
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
type ModelRules =
|
|
162
|
+
// simple allow/deny toggle.
|
|
163
|
+
| boolean
|
|
164
|
+
// more nuanced rules.
|
|
165
|
+
| {
|
|
166
|
+
// rules for all create operations.
|
|
167
|
+
create?: OperationRules;
|
|
168
|
+
// rules for all read operations.
|
|
169
|
+
read?: OperationRules;
|
|
170
|
+
// rules for all update operations.
|
|
171
|
+
update?: OperationRules;
|
|
172
|
+
// rules for all delete operations.
|
|
173
|
+
delete?: OperationRules;
|
|
174
|
+
// fallback in case the request's operation group doesn't have specific rules.
|
|
175
|
+
$allOperations?: OperationRules;
|
|
176
|
+
// will deny requests if at least one of these fields is in the request's
|
|
177
|
+
// arguments or is returned by the query. If an operation has specific
|
|
178
|
+
// $blockedFields, they will override this property.
|
|
179
|
+
// Example: ['password']
|
|
180
|
+
$blockedFields?: string[];
|
|
181
|
+
};
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Operation rules are best described by the following diagram:
|
|
185
|
+
|
|
186
|
+

|
|
187
|
+
|
|
188
|
+
It's like an 🧅.
|
|
189
|
+
|
|
190
|
+
`$where` overrides the incoming request's filtering by `AND`ing any existing filters with it.
|
|
191
|
+
|
|
192
|
+
The callback's `req` argument is an object that includes the model name, operation, args object, and the global context object.
|
|
193
|
+
|
|
194
|
+
`$rule` is a verbose way of defining both an access rule and additional rules/logic for a specific operation:
|
|
195
|
+
|
|
196
|
+
- `$before` allows running custom code before the query is executed by `PrismaClient`.
|
|
197
|
+
|
|
198
|
+
- `$after` allows running custom code after the query is executed by `PrismaClient`.
|
|
199
|
+
|
|
200
|
+
- `$blockedFields` behaves similarly to the one that can be defined at the model level, but overrides it if it exists.
|
|
201
|
+
|
|
202
|
+
#### Rule Evaluation
|
|
203
|
+
|
|
204
|
+
Here's a diagram depicting the rule engine's evaluation process in a simplified manner:
|
|
205
|
+
|
|
206
|
+

|
|
207
|
+
|
|
208
|
+
The rule engine is designed to introduce as little overhead as possible. As soon as a rule is not adhered by some check, the request is denied. Meaning, it doesn't try and run additional checks to collect more deny reasons.
|
|
209
|
+
|
|
210
|
+
## Need help?
|
|
211
|
+
|
|
212
|
+
If you need assistance, reach out in the #help-and-questions channel on our [Discord](https://pris.ly/discord), or connect with our community to see how others are using Prisma Security Rules.
|
|
Binary file
|
package/assets/rpc.png
ADDED
|
Binary file
|
|
Binary file
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var B=Object.defineProperty;var Pe=Object.getOwnPropertyDescriptor;var Ie=Object.getOwnPropertyNames;var Ne=Object.prototype.hasOwnProperty;var _e=(e,t)=>{for(var n in t)B(e,n,{get:t[n],enumerable:!0})},Ke=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Ie(t))!Ne.call(e,s)&&s!==n&&B(e,s,{get:()=>t[s],enumerable:!(r=Pe(t,s))||r.enumerable});return e};var Me=e=>Ke(B({},"__esModule",{value:!0}),e);var gt={};_e(gt,{AuthorizedClient:()=>Te,defineRules:()=>ee});module.exports=Me(gt);function ee(e){let{prisma:t,rules:n}=e;return Object.assign(t,{$rules:{setGlobalContext(r){},contextSchema:e.contextSchema?.["~standard"],rules:n}})}var c=require("zod");var P=class{constructor(){this.keyToValue=new Map,this.valueToKey=new Map}set(t,n){this.keyToValue.set(t,n),this.valueToKey.set(n,t)}getByKey(t){return this.keyToValue.get(t)}getByValue(t){return this.valueToKey.get(t)}clear(){this.keyToValue.clear(),this.valueToKey.clear()}};var b=class{constructor(t){this.generateIdentifier=t,this.kv=new P}register(t,n){this.kv.getByValue(t)||(n||(n=this.generateIdentifier(t)),this.kv.set(n,t))}clear(){this.kv.clear()}getIdentifier(t){return this.kv.getByValue(t)}getValue(t){return this.kv.getByKey(t)}};var I=class extends b{constructor(){super(t=>t.name),this.classToAllowedProps=new Map}register(t,n){typeof n=="object"?(n.allowProps&&this.classToAllowedProps.set(t,n.allowProps),super.register(t,n.identifier)):super.register(t,n)}getAllowedProps(t){return this.classToAllowedProps.get(t)}};function Ve(e){if("values"in Object)return Object.values(e);let t=[];for(let n in e)e.hasOwnProperty(n)&&t.push(e[n]);return t}function te(e,t){let n=Ve(e);if("find"in n)return n.find(t);let r=n;for(let s=0;s<r.length;s++){let o=r[s];if(t(o))return o}}function w(e,t){Object.entries(e).forEach(([n,r])=>t(r,n))}function A(e,t){return e.indexOf(t)!==-1}function L(e,t){for(let n=0;n<e.length;n++){let r=e[n];if(t(r))return r}}var N=class{constructor(){this.transfomers={}}register(t){this.transfomers[t.name]=t}findApplicable(t){return te(this.transfomers,n=>n.isApplicable(t))}findByName(t){return this.transfomers[t]}};var Ue=e=>Object.prototype.toString.call(e).slice(8,-1),v=e=>typeof e>"u",ze=e=>e===null,C=e=>typeof e!="object"||e===null||e===Object.prototype?!1:Object.getPrototypeOf(e)===null?!0:Object.getPrototypeOf(e)===Object.prototype,_=e=>C(e)&&Object.keys(e).length===0,x=e=>Array.isArray(e),De=e=>typeof e=="string",Be=e=>typeof e=="number"&&!isNaN(e),Le=e=>typeof e=="boolean",ne=e=>e instanceof RegExp,R=e=>e instanceof Map,h=e=>e instanceof Set,$=e=>Ue(e)==="Symbol",re=e=>e instanceof Date&&!isNaN(e.valueOf()),se=e=>e instanceof Error,j=e=>typeof e=="number"&&isNaN(e),oe=e=>Le(e)||ze(e)||v(e)||Be(e)||De(e)||$(e),ie=e=>typeof e=="bigint",ae=e=>e===1/0||e===-1/0,ue=e=>ArrayBuffer.isView(e)&&!(e instanceof DataView),ce=e=>e instanceof URL;var G=e=>e.replace(/\./g,"\\."),K=e=>e.map(String).map(G).join("."),E=e=>{let t=[],n="";for(let s=0;s<e.length;s++){let o=e.charAt(s);if(o==="\\"&&e.charAt(s+1)==="."){n+=".",s++;continue}if(o==="."){t.push(n),n="";continue}n+=o}let r=n;return t.push(r),t};function O(e,t,n,r){return{isApplicable:e,annotation:t,transform:n,untransform:r}}var le=[O(v,"undefined",()=>null,()=>{}),O(ie,"bigint",e=>e.toString(),e=>typeof BigInt<"u"?BigInt(e):(console.error("Please add a BigInt polyfill."),e)),O(re,"Date",e=>e.toISOString(),e=>new Date(e)),O(se,"Error",(e,t)=>{let n={name:e.name,message:e.message};return t.allowedErrorProps.forEach(r=>{n[r]=e[r]}),n},(e,t)=>{let n=new Error(e.message);return n.name=e.name,n.stack=e.stack,t.allowedErrorProps.forEach(r=>{n[r]=e[r]}),n}),O(ne,"regexp",e=>""+e,e=>{let t=e.slice(1,e.lastIndexOf("/")),n=e.slice(e.lastIndexOf("/")+1);return new RegExp(t,n)}),O(h,"set",e=>[...e.values()],e=>new Set(e)),O(R,"map",e=>[...e.entries()],e=>new Map(e)),O(e=>j(e)||ae(e),"number",e=>j(e)?"NaN":e>0?"Infinity":"-Infinity",Number),O(e=>e===0&&1/e===-1/0,"number",()=>"-0",Number),O(ce,"URL",e=>e.toString(),e=>new URL(e))];function M(e,t,n,r){return{isApplicable:e,annotation:t,transform:n,untransform:r}}var pe=M((e,t)=>$(e)?!!t.symbolRegistry.getIdentifier(e):!1,(e,t)=>["symbol",t.symbolRegistry.getIdentifier(e)],e=>e.description,(e,t,n)=>{let r=n.symbolRegistry.getValue(t[1]);if(!r)throw new Error("Trying to deserialize unknown symbol");return r}),ve=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,Uint8ClampedArray].reduce((e,t)=>(e[t.name]=t,e),{}),fe=M(ue,e=>["typed-array",e.constructor.name],e=>[...e],(e,t)=>{let n=ve[t[1]];if(!n)throw new Error("Trying to deserialize unknown typed array");return new n(e)});function F(e,t){return e?.constructor?!!t.classRegistry.getIdentifier(e.constructor):!1}var de=M(F,(e,t)=>["class",t.classRegistry.getIdentifier(e.constructor)],(e,t)=>{let n=t.classRegistry.getAllowedProps(e.constructor);if(!n)return{...e};let r={};return n.forEach(s=>{r[s]=e[s]}),r},(e,t,n)=>{let r=n.classRegistry.getValue(t[1]);if(!r)throw new Error(`Trying to deserialize unknown class '${t[1]}' - check https://github.com/blitz-js/superjson/issues/116#issuecomment-773996564`);return Object.assign(Object.create(r.prototype),e)}),ye=M((e,t)=>!!t.customTransformerRegistry.findApplicable(e),(e,t)=>["custom",t.customTransformerRegistry.findApplicable(e).name],(e,t)=>t.customTransformerRegistry.findApplicable(e).serialize(e),(e,t,n)=>{let r=n.customTransformerRegistry.findByName(t[1]);if(!r)throw new Error("Trying to deserialize unknown custom value");return r.deserialize(e)}),$e=[de,pe,ye,fe],X=(e,t)=>{let n=L($e,s=>s.isApplicable(e,t));if(n)return{value:n.transform(e,t),type:n.annotation(e,t)};let r=L(le,s=>s.isApplicable(e,t));if(r)return{value:r.transform(e,t),type:r.annotation}},me={};le.forEach(e=>{me[e.annotation]=e});var xe=(e,t,n)=>{if(x(t))switch(t[0]){case"symbol":return pe.untransform(e,t,n);case"class":return de.untransform(e,t,n);case"custom":return ye.untransform(e,t,n);case"typed-array":return fe.untransform(e,t,n);default:throw new Error("Unknown transformation: "+t)}else{let r=me[t];if(!r)throw new Error("Unknown transformation: "+t);return r.untransform(e,n)}};var T=(e,t)=>{if(t>e.size)throw new Error("index out of bounds");let n=e.keys();for(;t>0;)n.next(),t--;return n.next().value};function Se(e){if(A(e,"__proto__"))throw new Error("__proto__ is not allowed as a property");if(A(e,"prototype"))throw new Error("prototype is not allowed as a property");if(A(e,"constructor"))throw new Error("constructor is not allowed as a property")}var Oe=(e,t)=>{Se(t);for(let n=0;n<t.length;n++){let r=t[n];if(h(e))e=T(e,+r);else if(R(e)){let s=+r,o=+t[++n]==0?"key":"value",i=T(e,s);switch(o){case"key":e=i;break;case"value":e=e.get(i);break}}else e=e[r]}return e},V=(e,t,n)=>{if(Se(t),t.length===0)return n(e);let r=e;for(let o=0;o<t.length-1;o++){let i=t[o];if(x(r)){let l=+i;r=r[l]}else if(C(r))r=r[i];else if(h(r)){let l=+i;r=T(r,l)}else if(R(r)){if(o===t.length-2)break;let u=+i,d=+t[++o]==0?"key":"value",y=T(r,u);switch(d){case"key":r=y;break;case"value":r=r.get(y);break}}}let s=t[t.length-1];if(x(r)?r[+s]=n(r[+s]):C(r)&&(r[s]=n(r[s])),h(r)){let o=T(r,+s),i=n(o);o!==i&&(r.delete(o),r.add(i))}if(R(r)){let o=+t[t.length-2],i=T(r,o);switch(+s==0?"key":"value"){case"key":{let u=n(i);r.set(u,r.get(i)),u!==i&&r.delete(i);break}case"value":{r.set(i,n(r.get(i)));break}}}return e};function Q(e,t,n=[]){if(!e)return;if(!x(e)){w(e,(o,i)=>Q(o,t,[...n,...E(i)]));return}let[r,s]=e;s&&w(s,(o,i)=>{Q(o,t,[...n,...E(i)])}),t(r,n)}function ge(e,t,n){return Q(t,(r,s)=>{e=V(e,s,o=>xe(o,r,n))}),e}function Re(e,t){function n(r,s){let o=Oe(e,E(s));r.map(E).forEach(i=>{e=V(e,i,()=>o)})}if(x(t)){let[r,s]=t;r.forEach(o=>{e=V(e,E(o),()=>e)}),s&&w(s,n)}else w(t,n);return e}var je=(e,t)=>C(e)||x(e)||R(e)||h(e)||F(e,t);function Ge(e,t,n){let r=n.get(e);r?r.push(t):n.set(e,[t])}function he(e,t){let n={},r;return e.forEach(s=>{if(s.length<=1)return;t||(s=s.map(l=>l.map(String)).sort((l,u)=>l.length-u.length));let[o,...i]=s;o.length===0?r=i.map(K):n[K(o)]=i.map(K)}),r?_(n)?[r]:[r,n]:_(n)?void 0:n}var Y=(e,t,n,r,s=[],o=[],i=new Map)=>{let l=oe(e);if(!l){Ge(e,s,t);let m=i.get(e);if(m)return r?{transformedValue:null}:m}if(!je(e,n)){let m=X(e,n),f=m?{transformedValue:m.value,annotations:[m.type]}:{transformedValue:e};return l||i.set(e,f),f}if(A(o,e))return{transformedValue:null};let u=X(e,n),d=u?.value??e,y=x(d)?[]:{},g={};w(d,(m,f)=>{if(f==="__proto__"||f==="constructor"||f==="prototype")throw new Error(`Detected property ${f}. This is a prototype pollution risk, please remove it from your object.`);let p=Y(m,t,n,r,[...s,f],[...o,e],i);y[f]=p.transformedValue,x(p.annotations)?g[f]=p.annotations:C(p.annotations)&&w(p.annotations,(qe,ke)=>{g[G(f)+"."+ke]=qe})});let S=_(g)?{transformedValue:y,annotations:u?[u.type]:void 0}:{transformedValue:y,annotations:u?[u.type,g]:g};return l||i.set(e,S),S};function U(e){return Object.prototype.toString.call(e).slice(8,-1)}function W(e){return U(e)==="Array"}function we(e){if(U(e)!=="Object")return!1;let t=Object.getPrototypeOf(e);return!!t&&t.constructor===Object&&t===Object.prototype}function Fe(e){return U(e)==="Null"}function Xe(e,t,n,r,s){return o=>e(o)||t(o)||!!n&&n(o)||!!r&&r(o)||!!s&&s(o)}function Qe(e){return U(e)==="Undefined"}var Gt=Xe(Fe,Qe);function Ye(e,t,n,r,s){let o={}.propertyIsEnumerable.call(r,t)?"enumerable":"nonenumerable";o==="enumerable"&&(e[t]=n),s&&o==="nonenumerable"&&Object.defineProperty(e,t,{value:n,enumerable:!1,writable:!0,configurable:!0})}function z(e,t={}){if(W(e))return e.map(s=>z(s,t));if(!we(e))return e;let n=Object.getOwnPropertyNames(e),r=Object.getOwnPropertySymbols(e);return[...n,...r].reduce((s,o)=>{if(W(t.props)&&!t.props.includes(o))return s;let i=e[o],l=z(i,t);return Ye(s,o,l,e,t.nonenumerable),s},{})}var a=class{constructor({dedupe:t=!1}={}){this.classRegistry=new I,this.symbolRegistry=new b(n=>n.description??""),this.customTransformerRegistry=new N,this.allowedErrorProps=[],this.dedupe=t}serialize(t){let n=new Map,r=Y(t,n,this,this.dedupe),s={json:r.transformedValue};r.annotations&&(s.meta={...s.meta,values:r.annotations});let o=he(n,this.dedupe);return o&&(s.meta={...s.meta,referentialEqualities:o}),s}deserialize(t){let{json:n,meta:r}=t,s=z(n);return r?.values&&(s=ge(s,r.values,this)),r?.referentialEqualities&&(s=Re(s,r.referentialEqualities)),s}stringify(t){return JSON.stringify(this.serialize(t))}parse(t){return this.deserialize(JSON.parse(t))}registerClass(t,n){this.classRegistry.register(t,n)}registerSymbol(t,n){this.symbolRegistry.register(t,n)}registerCustom(t,n){this.customTransformerRegistry.register({name:n,...t})}allowErrorProps(...t){this.allowedErrorProps.push(...t)}};a.defaultInstance=new a;a.serialize=a.defaultInstance.serialize.bind(a.defaultInstance);a.deserialize=a.defaultInstance.deserialize.bind(a.defaultInstance);a.stringify=a.defaultInstance.stringify.bind(a.defaultInstance);a.parse=a.defaultInstance.parse.bind(a.defaultInstance);a.registerClass=a.defaultInstance.registerClass.bind(a.defaultInstance);a.registerSymbol=a.defaultInstance.registerSymbol.bind(a.defaultInstance);a.registerCustom=a.defaultInstance.registerCustom.bind(a.defaultInstance);a.allowErrorProps=a.defaultInstance.allowErrorProps.bind(a.defaultInstance);var en=a.serialize,tn=a.deserialize,q=a.stringify,k=a.parse,nn=a.registerClass,H=a.registerCustom,rn=a.registerSymbol,sn=a.allowErrorProps;var We=()=>H({isApplicable:e=>e?.constructor?.name==="Buffer",serialize:e=>q(new Uint8Array(e)),deserialize:e=>k(e)},"buffer"),He=()=>H({isApplicable:e=>e!==null&&typeof e=="object"&&typeof Reflect.get(e,"s")=="number"&&typeof Reflect.get(e,"e")=="number"&&typeof Reflect.get(e,"toFixed")=="function"&&Array.isArray(Reflect.get(e,"d")),serialize:e=>{throw new Error("Decimal is not yet supported")},deserialize:e=>{new Error("Decimal is not yet supported")}},"decimaljs"),Z=()=>{We(),He()};var Ze=c.z.tuple([c.z.literal("GET").describe("kind"),c.z.string().min(1).describe("model")]),Je=c.z.enum(["findMany","findFirst","count","findFirstOrThrow","findUnique","findUniqueOrThrow","create","update","delete","upsert","createMany","updateMany","deleteMany","createManyAndReturn","updateManyAndReturn","aggregate","groupBy"]),et=c.z.tuple([c.z.literal("GET").describe("kind"),Je]),tt=c.z.tuple([c.z.literal("CALL").describe("kind"),c.z.array(c.z.unknown()).readonly().describe("args")]),nt=c.z.tuple([c.z.literal("WAIT").describe("kind")]),rt=c.z.tuple([c.z.literal("COMMIT_ITX").describe("kind")]),st=c.z.tuple([c.z.literal("ROLLBACK_ITX").describe("kind")]),ot=c.z.tuple([Ze,et,tt.describe("args"),nt.describe("then")]),it=c.z.tuple([rt]),at=c.z.tuple([st]),ut=c.z.union([ot,it,at]),ln=c.z.object({kind:c.z.literal("SEQUENCE_REQUEST"),globalContext:c.z.unknown().nullish(),uuid:c.z.string().min(1),sequence:ut,version:c.z.string().nullish()});var pn=Symbol("SequenceResponse");Z();var J="SEQUENCE_REQUEST",ct="wss://rules-dispatcher.datacdn.workers.dev/",Ce=3e4,lt=15e3;function D(e){return new Proxy(()=>{},{apply:dt(e),get:xt(e)})}function be(e){return{kind:J,uuid:crypto.randomUUID(),sequence:[...e?.sequence??[]],globalContext:e?.globalContext}}async function pt({ws:e,args:t}){let{url:n,searchParams:r}=e.args,[s,...o]=t,i=crypto.randomUUID(),l=Ae({url:n,searchParams:{...r,itx:JSON.stringify(t)}}),u=s(D({ws:l}));return u.then(()=>l.send({kind:J,uuid:i,sequence:[["COMMIT_ITX"]]})).catch(()=>l.send({kind:J,uuid:i,sequence:[["ROLLBACK_ITX"]]})),await u}async function ft(){throw new Error("Batch transactions are not yet supported")}function dt({ws:e,...t}){return(n,r,s)=>{if(t.prop==="$transaction")return typeof s[0]=="function"?pt({ws:e,args:s}):ft();let o=be(t.payload);return o.sequence.push(["CALL",s]),D({ws:e,payload:o})}}function yt({ws:e,payload:t,prop:n}){t.sequence.push(["WAIT"]);let r=e.send(t);return r[n].bind(r)}function mt(e){return{setGlobalContext(t){Ee=t}}}function xt({ws:e,...t}){return(n,r)=>{let s=be(t.payload);if(r==="then"||r==="catch"||r==="finally")return yt({ws:e,payload:s,prop:r});if(r==="$rules")return mt({ws:e,payload:s,prop:r});if(s.sequence.push(["GET",r]),St(s.sequence))throw new Error("Model field references are not yet supported");return D({...t,ws:e,payload:s,prop:r})}}function St(e){return e[0]?.[0]==="GET"&&e[1]?.[0]==="GET"&&e[1]?.[1]==="fields"}function Ae(e={}){let t={},{url:n=ct,searchParams:r={}}=e,s;async function o(){if(s===void 0)return await i();let{ws:u,date:d}=s;return u===void 0||Date.now()-d>=lt?(setTimeout(()=>u?.close(),Ce),await i()):{ws:u,date:d}}async function i(u=0){let d=await new Promise((y,g)=>{let S=new WebSocket(`${n}?${new URLSearchParams(r).toString()}`),m=Date.now();S.addEventListener("error",()=>g()),S.addEventListener("open",()=>y({ws:S,date:m})),S.addEventListener("close",()=>delete d.ws),S.addEventListener("message",({data:f})=>{let p=k(f);p.kind==="SEQUENCE_RESPONSE_ALLOW"&&t[p.uuid]?.resolve(p.result),p.kind==="SEQUENCE_RESPONSE_DENY"&&t[p.uuid]?.reject(new Error(p.reason)),p.kind==="SEQUENCE_RESPONSE_ERROR"&&t[p.uuid]?.reject(new Error(p.reason)),p.uuid&&delete t[p.uuid]})}).catch(async()=>(await new Promise(y=>setTimeout(y,1e3*u)),console.warn("Failed to connect to the server, retrying..."),await i(u+1)));return s=d}async function l(u){let d,y=new Promise((...f)=>d=f),[g,S]=d;u.globalContext=Ee,t[u.uuid]={resolve:g,reject:S},(await o()).ws.send(q(u));let m=setTimeout(()=>{t[u.uuid]?.reject(new Error("Operation timed out")),delete t[u.uuid]},Ce);return await y.finally(()=>clearTimeout(m))}return{send:l,args:e}}function Ot(e){let{url:t,publicKey:n}=e;return D({ws:Ae({url:t,searchParams:{publicKey:n}})})}var Ee,Te=Ot;0&&(module.exports={AuthorizedClient,defineRules});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Prisma } from '@prisma/client/extension';
|
|
2
|
+
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
3
|
+
|
|
4
|
+
declare type Narrowable = string | number | bigint | boolean | [];
|
|
5
|
+
declare type Exact<A, W> = (A extends unknown ? W extends A ? {
|
|
6
|
+
[K in keyof A]: Exact<A[K], W[K]>;
|
|
7
|
+
} : W : never) | (A extends Narrowable ? A : never);
|
|
8
|
+
type CoerceAnyToNever<T> = unknown extends T ? never : T;
|
|
9
|
+
type CoerceNeverToValue<T, V> = [T] extends [never] ? V : T;
|
|
10
|
+
type ModelKeys<T> = {
|
|
11
|
+
[K in keyof T]: K extends `$${string}` ? never : K;
|
|
12
|
+
}[keyof T];
|
|
13
|
+
type Rules<C, Ctx extends StandardSchemaV1, AllModelKeys extends ModelKeys<C> = ModelKeys<C>> = {
|
|
14
|
+
[K in AllModelKeys]?: {
|
|
15
|
+
read?: OpRuleShape<ReadOperation, C, K, Ctx>;
|
|
16
|
+
create?: OpRuleShape<CreateOperation, C, K, Ctx>;
|
|
17
|
+
delete?: OpRuleShape<DeleteOperation, C, K, Ctx>;
|
|
18
|
+
update?: OpRuleShape<UpdateOperation, C, K, Ctx>;
|
|
19
|
+
$allOperations?: OpRuleShape<Operation, C, K, Ctx>;
|
|
20
|
+
} | boolean;
|
|
21
|
+
} & {
|
|
22
|
+
$transaction?: boolean;
|
|
23
|
+
$allModels?: {
|
|
24
|
+
read?: AnyOpRuleShape<ReadOperation, Ctx>;
|
|
25
|
+
create?: AnyOpRuleShape<CreateOperation, Ctx>;
|
|
26
|
+
delete?: AnyOpRuleShape<DeleteOperation, Ctx>;
|
|
27
|
+
update?: AnyOpRuleShape<UpdateOperation, Ctx>;
|
|
28
|
+
$allOperations?: AnyOpRuleShape<Operation, Ctx>;
|
|
29
|
+
} | boolean;
|
|
30
|
+
};
|
|
31
|
+
/** <Operation> */
|
|
32
|
+
type DeleteOperation = "delete" | "deleteMany";
|
|
33
|
+
type UpdateOperation = "update" | "updateMany" | "updateManyAndReturn" | "upsert";
|
|
34
|
+
type CreateOperation = "create" | "upsert" | "createMany" | "createManyAndReturn";
|
|
35
|
+
type ReadOperation = "aggregate" | "count" | "findFirst" | "findFirstOrThrow" | "findMany" | "findUnique" | "findUniqueOrThrow" | "groupBy";
|
|
36
|
+
type Operation = CreateOperation | DeleteOperation | UpdateOperation | ReadOperation;
|
|
37
|
+
/** <Operation:Model> */
|
|
38
|
+
type OpRuleShape<O extends Operation, C, K extends keyof C, Ctx extends StandardSchemaV1> = boolean | OpRuleShapeWhere<O, C, K> | OpRuleShapeCallback<O, C, K, Ctx> | OpRuleShapeVerbose<O, C, K, Ctx>;
|
|
39
|
+
type OpRuleShapeWhere<O extends Operation, C, K extends keyof C> = Prisma.Args<C[K], O> extends {
|
|
40
|
+
where?: infer W;
|
|
41
|
+
} ? {
|
|
42
|
+
$where: W;
|
|
43
|
+
$rule?: never;
|
|
44
|
+
} : never;
|
|
45
|
+
type OpCtx<O extends Operation, C, K extends keyof C, Ctx extends StandardSchemaV1> = K extends unknown ? O extends unknown ? {
|
|
46
|
+
model: K;
|
|
47
|
+
operation: O;
|
|
48
|
+
args: CoerceAnyToNever<Prisma.Args<C[K], O>>;
|
|
49
|
+
context: StandardSchemaV1.InferOutput<Ctx>;
|
|
50
|
+
uuid?: string;
|
|
51
|
+
} : never : never;
|
|
52
|
+
type OpRuleShapeCallback<O extends Operation, C, K extends keyof C, Ctx extends StandardSchemaV1> = {
|
|
53
|
+
(ctx: OpCtx<O, C, K, Ctx>): MaybePromise<boolean | OpRuleShapeWhere<O, C, K>>;
|
|
54
|
+
};
|
|
55
|
+
type OpRuleShapeBefore<O extends Operation, C, K extends keyof C, Ctx extends StandardSchemaV1> = {
|
|
56
|
+
(ctx: OpCtx<O, C, K, Ctx>): MaybePromise<void>;
|
|
57
|
+
};
|
|
58
|
+
type OpRuleShapeAfter<O extends Operation, C, K extends keyof C, Ctx extends StandardSchemaV1> = {
|
|
59
|
+
(ctx: OpCtx<O, C, K, Ctx> & {
|
|
60
|
+
result: unknown;
|
|
61
|
+
}): MaybePromise<void>;
|
|
62
|
+
};
|
|
63
|
+
type OpRuleShapeVerbose<O extends Operation, C, K extends keyof C, Ctx extends StandardSchemaV1> = {
|
|
64
|
+
$rule: boolean | OpRuleShapeWhere<O, C, K> | OpRuleShapeCallback<O, C, K, Ctx>;
|
|
65
|
+
$after?: OpRuleShapeAfter<O, C, K, Ctx>;
|
|
66
|
+
$before?: OpRuleShapeBefore<O, C, K, Ctx>;
|
|
67
|
+
$blockedFields?: FieldsOf<O, C, K>[];
|
|
68
|
+
$where?: never;
|
|
69
|
+
};
|
|
70
|
+
/** </Operation:Model> */
|
|
71
|
+
/** <Operation:Any> */
|
|
72
|
+
type AnyOpRuleShape<O extends Operation, Ctx extends StandardSchemaV1> = boolean | AnyOpRuleShapeCallback<O, Ctx> | AnyOpRuleShapeVerbose<O, Ctx>;
|
|
73
|
+
type AnyOpRuleShapeWhere = object;
|
|
74
|
+
type AnyOpCtx<O extends Operation, Ctx extends StandardSchemaV1> = {
|
|
75
|
+
model: string;
|
|
76
|
+
operation: O;
|
|
77
|
+
args: object;
|
|
78
|
+
context: StandardSchemaV1.InferOutput<Ctx>;
|
|
79
|
+
uuid?: string;
|
|
80
|
+
};
|
|
81
|
+
type AnyOpRuleShapeCallback<O extends Operation, Ctx extends StandardSchemaV1> = {
|
|
82
|
+
(ctx: AnyOpCtx<O, Ctx>): MaybePromise<boolean | AnyOpRuleShapeWhere>;
|
|
83
|
+
};
|
|
84
|
+
type AnyOpRuleShapeBefore<O extends Operation, Ctx extends StandardSchemaV1> = {
|
|
85
|
+
(ctx: AnyOpCtx<O, Ctx>): MaybePromise<void>;
|
|
86
|
+
};
|
|
87
|
+
type AnyOpRuleShapeAfter<O extends Operation, Ctx extends StandardSchemaV1> = {
|
|
88
|
+
(ctx: AnyOpCtx<O, Ctx> & {
|
|
89
|
+
result: unknown;
|
|
90
|
+
}): MaybePromise<void>;
|
|
91
|
+
};
|
|
92
|
+
type AnyOpRuleShapeVerbose<O extends Operation, Ctx extends StandardSchemaV1> = {
|
|
93
|
+
$rule: boolean | AnyOpRuleShapeCallback<O, Ctx>;
|
|
94
|
+
$after?: AnyOpRuleShapeAfter<O, Ctx>;
|
|
95
|
+
$before?: AnyOpRuleShapeBefore<O, Ctx>;
|
|
96
|
+
$blockedFields?: string[];
|
|
97
|
+
};
|
|
98
|
+
/** </Operation:Any> */
|
|
99
|
+
/** </Operation> */
|
|
100
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
101
|
+
type FieldsOf<O extends Operation, C, K extends keyof C, P extends Record<string, unknown> = Prisma.Payload<C[K], O>> = CoerceNeverToValue<keyof P["scalars"] | keyof P["objects"] | keyof P["composites"], string>;
|
|
102
|
+
declare function defineRules<C extends object, R, CtxSchema extends StandardSchemaV1 = StandardSchemaV1>(args: {
|
|
103
|
+
prisma: C;
|
|
104
|
+
contextSchema?: CtxSchema;
|
|
105
|
+
rules: Exact<R, Rules<C, CtxSchema>>;
|
|
106
|
+
}): C & {
|
|
107
|
+
$rules: {
|
|
108
|
+
setGlobalContext(ctx: StandardSchemaV1.InferInput<CtxSchema>): void;
|
|
109
|
+
contextSchema: unknown;
|
|
110
|
+
rules: Exact<R, Rules<C, CtxSchema, ModelKeys<C>>>;
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Allow only accessing the models on the client object.
|
|
116
|
+
*/
|
|
117
|
+
type KeepObjectsOnly<T> = {
|
|
118
|
+
[K in keyof T as K extends `$${string}` ? (K extends "$transaction" | "$rules" ? K : never) : K]: T[K];
|
|
119
|
+
};
|
|
120
|
+
type AuthorizedClient<T> = KeepObjectsOnly<T>;
|
|
121
|
+
declare const AuthorizedClient: new <T>(args: {
|
|
122
|
+
url?: string;
|
|
123
|
+
publicKey: string;
|
|
124
|
+
}) => AuthorizedClient<T>;
|
|
125
|
+
|
|
126
|
+
export { AuthorizedClient, defineRules };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Prisma } from '@prisma/client/extension';
|
|
2
|
+
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
3
|
+
|
|
4
|
+
declare type Narrowable = string | number | bigint | boolean | [];
|
|
5
|
+
declare type Exact<A, W> = (A extends unknown ? W extends A ? {
|
|
6
|
+
[K in keyof A]: Exact<A[K], W[K]>;
|
|
7
|
+
} : W : never) | (A extends Narrowable ? A : never);
|
|
8
|
+
type CoerceAnyToNever<T> = unknown extends T ? never : T;
|
|
9
|
+
type CoerceNeverToValue<T, V> = [T] extends [never] ? V : T;
|
|
10
|
+
type ModelKeys<T> = {
|
|
11
|
+
[K in keyof T]: K extends `$${string}` ? never : K;
|
|
12
|
+
}[keyof T];
|
|
13
|
+
type Rules<C, Ctx extends StandardSchemaV1, AllModelKeys extends ModelKeys<C> = ModelKeys<C>> = {
|
|
14
|
+
[K in AllModelKeys]?: {
|
|
15
|
+
read?: OpRuleShape<ReadOperation, C, K, Ctx>;
|
|
16
|
+
create?: OpRuleShape<CreateOperation, C, K, Ctx>;
|
|
17
|
+
delete?: OpRuleShape<DeleteOperation, C, K, Ctx>;
|
|
18
|
+
update?: OpRuleShape<UpdateOperation, C, K, Ctx>;
|
|
19
|
+
$allOperations?: OpRuleShape<Operation, C, K, Ctx>;
|
|
20
|
+
} | boolean;
|
|
21
|
+
} & {
|
|
22
|
+
$transaction?: boolean;
|
|
23
|
+
$allModels?: {
|
|
24
|
+
read?: AnyOpRuleShape<ReadOperation, Ctx>;
|
|
25
|
+
create?: AnyOpRuleShape<CreateOperation, Ctx>;
|
|
26
|
+
delete?: AnyOpRuleShape<DeleteOperation, Ctx>;
|
|
27
|
+
update?: AnyOpRuleShape<UpdateOperation, Ctx>;
|
|
28
|
+
$allOperations?: AnyOpRuleShape<Operation, Ctx>;
|
|
29
|
+
} | boolean;
|
|
30
|
+
};
|
|
31
|
+
/** <Operation> */
|
|
32
|
+
type DeleteOperation = "delete" | "deleteMany";
|
|
33
|
+
type UpdateOperation = "update" | "updateMany" | "updateManyAndReturn" | "upsert";
|
|
34
|
+
type CreateOperation = "create" | "upsert" | "createMany" | "createManyAndReturn";
|
|
35
|
+
type ReadOperation = "aggregate" | "count" | "findFirst" | "findFirstOrThrow" | "findMany" | "findUnique" | "findUniqueOrThrow" | "groupBy";
|
|
36
|
+
type Operation = CreateOperation | DeleteOperation | UpdateOperation | ReadOperation;
|
|
37
|
+
/** <Operation:Model> */
|
|
38
|
+
type OpRuleShape<O extends Operation, C, K extends keyof C, Ctx extends StandardSchemaV1> = boolean | OpRuleShapeWhere<O, C, K> | OpRuleShapeCallback<O, C, K, Ctx> | OpRuleShapeVerbose<O, C, K, Ctx>;
|
|
39
|
+
type OpRuleShapeWhere<O extends Operation, C, K extends keyof C> = Prisma.Args<C[K], O> extends {
|
|
40
|
+
where?: infer W;
|
|
41
|
+
} ? {
|
|
42
|
+
$where: W;
|
|
43
|
+
$rule?: never;
|
|
44
|
+
} : never;
|
|
45
|
+
type OpCtx<O extends Operation, C, K extends keyof C, Ctx extends StandardSchemaV1> = K extends unknown ? O extends unknown ? {
|
|
46
|
+
model: K;
|
|
47
|
+
operation: O;
|
|
48
|
+
args: CoerceAnyToNever<Prisma.Args<C[K], O>>;
|
|
49
|
+
context: StandardSchemaV1.InferOutput<Ctx>;
|
|
50
|
+
uuid?: string;
|
|
51
|
+
} : never : never;
|
|
52
|
+
type OpRuleShapeCallback<O extends Operation, C, K extends keyof C, Ctx extends StandardSchemaV1> = {
|
|
53
|
+
(ctx: OpCtx<O, C, K, Ctx>): MaybePromise<boolean | OpRuleShapeWhere<O, C, K>>;
|
|
54
|
+
};
|
|
55
|
+
type OpRuleShapeBefore<O extends Operation, C, K extends keyof C, Ctx extends StandardSchemaV1> = {
|
|
56
|
+
(ctx: OpCtx<O, C, K, Ctx>): MaybePromise<void>;
|
|
57
|
+
};
|
|
58
|
+
type OpRuleShapeAfter<O extends Operation, C, K extends keyof C, Ctx extends StandardSchemaV1> = {
|
|
59
|
+
(ctx: OpCtx<O, C, K, Ctx> & {
|
|
60
|
+
result: unknown;
|
|
61
|
+
}): MaybePromise<void>;
|
|
62
|
+
};
|
|
63
|
+
type OpRuleShapeVerbose<O extends Operation, C, K extends keyof C, Ctx extends StandardSchemaV1> = {
|
|
64
|
+
$rule: boolean | OpRuleShapeWhere<O, C, K> | OpRuleShapeCallback<O, C, K, Ctx>;
|
|
65
|
+
$after?: OpRuleShapeAfter<O, C, K, Ctx>;
|
|
66
|
+
$before?: OpRuleShapeBefore<O, C, K, Ctx>;
|
|
67
|
+
$blockedFields?: FieldsOf<O, C, K>[];
|
|
68
|
+
$where?: never;
|
|
69
|
+
};
|
|
70
|
+
/** </Operation:Model> */
|
|
71
|
+
/** <Operation:Any> */
|
|
72
|
+
type AnyOpRuleShape<O extends Operation, Ctx extends StandardSchemaV1> = boolean | AnyOpRuleShapeCallback<O, Ctx> | AnyOpRuleShapeVerbose<O, Ctx>;
|
|
73
|
+
type AnyOpRuleShapeWhere = object;
|
|
74
|
+
type AnyOpCtx<O extends Operation, Ctx extends StandardSchemaV1> = {
|
|
75
|
+
model: string;
|
|
76
|
+
operation: O;
|
|
77
|
+
args: object;
|
|
78
|
+
context: StandardSchemaV1.InferOutput<Ctx>;
|
|
79
|
+
uuid?: string;
|
|
80
|
+
};
|
|
81
|
+
type AnyOpRuleShapeCallback<O extends Operation, Ctx extends StandardSchemaV1> = {
|
|
82
|
+
(ctx: AnyOpCtx<O, Ctx>): MaybePromise<boolean | AnyOpRuleShapeWhere>;
|
|
83
|
+
};
|
|
84
|
+
type AnyOpRuleShapeBefore<O extends Operation, Ctx extends StandardSchemaV1> = {
|
|
85
|
+
(ctx: AnyOpCtx<O, Ctx>): MaybePromise<void>;
|
|
86
|
+
};
|
|
87
|
+
type AnyOpRuleShapeAfter<O extends Operation, Ctx extends StandardSchemaV1> = {
|
|
88
|
+
(ctx: AnyOpCtx<O, Ctx> & {
|
|
89
|
+
result: unknown;
|
|
90
|
+
}): MaybePromise<void>;
|
|
91
|
+
};
|
|
92
|
+
type AnyOpRuleShapeVerbose<O extends Operation, Ctx extends StandardSchemaV1> = {
|
|
93
|
+
$rule: boolean | AnyOpRuleShapeCallback<O, Ctx>;
|
|
94
|
+
$after?: AnyOpRuleShapeAfter<O, Ctx>;
|
|
95
|
+
$before?: AnyOpRuleShapeBefore<O, Ctx>;
|
|
96
|
+
$blockedFields?: string[];
|
|
97
|
+
};
|
|
98
|
+
/** </Operation:Any> */
|
|
99
|
+
/** </Operation> */
|
|
100
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
101
|
+
type FieldsOf<O extends Operation, C, K extends keyof C, P extends Record<string, unknown> = Prisma.Payload<C[K], O>> = CoerceNeverToValue<keyof P["scalars"] | keyof P["objects"] | keyof P["composites"], string>;
|
|
102
|
+
declare function defineRules<C extends object, R, CtxSchema extends StandardSchemaV1 = StandardSchemaV1>(args: {
|
|
103
|
+
prisma: C;
|
|
104
|
+
contextSchema?: CtxSchema;
|
|
105
|
+
rules: Exact<R, Rules<C, CtxSchema>>;
|
|
106
|
+
}): C & {
|
|
107
|
+
$rules: {
|
|
108
|
+
setGlobalContext(ctx: StandardSchemaV1.InferInput<CtxSchema>): void;
|
|
109
|
+
contextSchema: unknown;
|
|
110
|
+
rules: Exact<R, Rules<C, CtxSchema, ModelKeys<C>>>;
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Allow only accessing the models on the client object.
|
|
116
|
+
*/
|
|
117
|
+
type KeepObjectsOnly<T> = {
|
|
118
|
+
[K in keyof T as K extends `$${string}` ? (K extends "$transaction" | "$rules" ? K : never) : K]: T[K];
|
|
119
|
+
};
|
|
120
|
+
type AuthorizedClient<T> = KeepObjectsOnly<T>;
|
|
121
|
+
declare const AuthorizedClient: new <T>(args: {
|
|
122
|
+
url?: string;
|
|
123
|
+
publicKey: string;
|
|
124
|
+
}) => AuthorizedClient<T>;
|
|
125
|
+
|
|
126
|
+
export { AuthorizedClient, defineRules };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function Te(e){let{prisma:t,rules:n}=e;return Object.assign(t,{$rules:{setGlobalContext(r){},contextSchema:e.contextSchema?.["~standard"],rules:n}})}import{z as c}from"zod";var P=class{constructor(){this.keyToValue=new Map,this.valueToKey=new Map}set(t,n){this.keyToValue.set(t,n),this.valueToKey.set(n,t)}getByKey(t){return this.keyToValue.get(t)}getByValue(t){return this.valueToKey.get(t)}clear(){this.keyToValue.clear(),this.valueToKey.clear()}};var b=class{constructor(t){this.generateIdentifier=t,this.kv=new P}register(t,n){this.kv.getByValue(t)||(n||(n=this.generateIdentifier(t)),this.kv.set(n,t))}clear(){this.kv.clear()}getIdentifier(t){return this.kv.getByValue(t)}getValue(t){return this.kv.getByKey(t)}};var I=class extends b{constructor(){super(t=>t.name),this.classToAllowedProps=new Map}register(t,n){typeof n=="object"?(n.allowProps&&this.classToAllowedProps.set(t,n.allowProps),super.register(t,n.identifier)):super.register(t,n)}getAllowedProps(t){return this.classToAllowedProps.get(t)}};function qe(e){if("values"in Object)return Object.values(e);let t=[];for(let n in e)e.hasOwnProperty(n)&&t.push(e[n]);return t}function J(e,t){let n=qe(e);if("find"in n)return n.find(t);let r=n;for(let s=0;s<r.length;s++){let o=r[s];if(t(o))return o}}function w(e,t){Object.entries(e).forEach(([n,r])=>t(r,n))}function A(e,t){return e.indexOf(t)!==-1}function B(e,t){for(let n=0;n<e.length;n++){let r=e[n];if(t(r))return r}}var N=class{constructor(){this.transfomers={}}register(t){this.transfomers[t.name]=t}findApplicable(t){return J(this.transfomers,n=>n.isApplicable(t))}findByName(t){return this.transfomers[t]}};var ke=e=>Object.prototype.toString.call(e).slice(8,-1),L=e=>typeof e>"u",Pe=e=>e===null,C=e=>typeof e!="object"||e===null||e===Object.prototype?!1:Object.getPrototypeOf(e)===null?!0:Object.getPrototypeOf(e)===Object.prototype,_=e=>C(e)&&Object.keys(e).length===0,x=e=>Array.isArray(e),Ie=e=>typeof e=="string",Ne=e=>typeof e=="number"&&!isNaN(e),_e=e=>typeof e=="boolean",ee=e=>e instanceof RegExp,R=e=>e instanceof Map,h=e=>e instanceof Set,v=e=>ke(e)==="Symbol",te=e=>e instanceof Date&&!isNaN(e.valueOf()),ne=e=>e instanceof Error,$=e=>typeof e=="number"&&isNaN(e),re=e=>_e(e)||Pe(e)||L(e)||Ne(e)||Ie(e)||v(e),se=e=>typeof e=="bigint",oe=e=>e===1/0||e===-1/0,ie=e=>ArrayBuffer.isView(e)&&!(e instanceof DataView),ae=e=>e instanceof URL;var j=e=>e.replace(/\./g,"\\."),K=e=>e.map(String).map(j).join("."),E=e=>{let t=[],n="";for(let s=0;s<e.length;s++){let o=e.charAt(s);if(o==="\\"&&e.charAt(s+1)==="."){n+=".",s++;continue}if(o==="."){t.push(n),n="";continue}n+=o}let r=n;return t.push(r),t};function O(e,t,n,r){return{isApplicable:e,annotation:t,transform:n,untransform:r}}var ue=[O(L,"undefined",()=>null,()=>{}),O(se,"bigint",e=>e.toString(),e=>typeof BigInt<"u"?BigInt(e):(console.error("Please add a BigInt polyfill."),e)),O(te,"Date",e=>e.toISOString(),e=>new Date(e)),O(ne,"Error",(e,t)=>{let n={name:e.name,message:e.message};return t.allowedErrorProps.forEach(r=>{n[r]=e[r]}),n},(e,t)=>{let n=new Error(e.message);return n.name=e.name,n.stack=e.stack,t.allowedErrorProps.forEach(r=>{n[r]=e[r]}),n}),O(ee,"regexp",e=>""+e,e=>{let t=e.slice(1,e.lastIndexOf("/")),n=e.slice(e.lastIndexOf("/")+1);return new RegExp(t,n)}),O(h,"set",e=>[...e.values()],e=>new Set(e)),O(R,"map",e=>[...e.entries()],e=>new Map(e)),O(e=>$(e)||oe(e),"number",e=>$(e)?"NaN":e>0?"Infinity":"-Infinity",Number),O(e=>e===0&&1/e===-1/0,"number",()=>"-0",Number),O(ae,"URL",e=>e.toString(),e=>new URL(e))];function M(e,t,n,r){return{isApplicable:e,annotation:t,transform:n,untransform:r}}var ce=M((e,t)=>v(e)?!!t.symbolRegistry.getIdentifier(e):!1,(e,t)=>["symbol",t.symbolRegistry.getIdentifier(e)],e=>e.description,(e,t,n)=>{let r=n.symbolRegistry.getValue(t[1]);if(!r)throw new Error("Trying to deserialize unknown symbol");return r}),Ke=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,Uint8ClampedArray].reduce((e,t)=>(e[t.name]=t,e),{}),le=M(ie,e=>["typed-array",e.constructor.name],e=>[...e],(e,t)=>{let n=Ke[t[1]];if(!n)throw new Error("Trying to deserialize unknown typed array");return new n(e)});function G(e,t){return e?.constructor?!!t.classRegistry.getIdentifier(e.constructor):!1}var pe=M(G,(e,t)=>["class",t.classRegistry.getIdentifier(e.constructor)],(e,t)=>{let n=t.classRegistry.getAllowedProps(e.constructor);if(!n)return{...e};let r={};return n.forEach(s=>{r[s]=e[s]}),r},(e,t,n)=>{let r=n.classRegistry.getValue(t[1]);if(!r)throw new Error(`Trying to deserialize unknown class '${t[1]}' - check https://github.com/blitz-js/superjson/issues/116#issuecomment-773996564`);return Object.assign(Object.create(r.prototype),e)}),fe=M((e,t)=>!!t.customTransformerRegistry.findApplicable(e),(e,t)=>["custom",t.customTransformerRegistry.findApplicable(e).name],(e,t)=>t.customTransformerRegistry.findApplicable(e).serialize(e),(e,t,n)=>{let r=n.customTransformerRegistry.findByName(t[1]);if(!r)throw new Error("Trying to deserialize unknown custom value");return r.deserialize(e)}),Me=[pe,ce,fe,le],F=(e,t)=>{let n=B(Me,s=>s.isApplicable(e,t));if(n)return{value:n.transform(e,t),type:n.annotation(e,t)};let r=B(ue,s=>s.isApplicable(e,t));if(r)return{value:r.transform(e,t),type:r.annotation}},de={};ue.forEach(e=>{de[e.annotation]=e});var ye=(e,t,n)=>{if(x(t))switch(t[0]){case"symbol":return ce.untransform(e,t,n);case"class":return pe.untransform(e,t,n);case"custom":return fe.untransform(e,t,n);case"typed-array":return le.untransform(e,t,n);default:throw new Error("Unknown transformation: "+t)}else{let r=de[t];if(!r)throw new Error("Unknown transformation: "+t);return r.untransform(e,n)}};var T=(e,t)=>{if(t>e.size)throw new Error("index out of bounds");let n=e.keys();for(;t>0;)n.next(),t--;return n.next().value};function me(e){if(A(e,"__proto__"))throw new Error("__proto__ is not allowed as a property");if(A(e,"prototype"))throw new Error("prototype is not allowed as a property");if(A(e,"constructor"))throw new Error("constructor is not allowed as a property")}var xe=(e,t)=>{me(t);for(let n=0;n<t.length;n++){let r=t[n];if(h(e))e=T(e,+r);else if(R(e)){let s=+r,o=+t[++n]==0?"key":"value",i=T(e,s);switch(o){case"key":e=i;break;case"value":e=e.get(i);break}}else e=e[r]}return e},V=(e,t,n)=>{if(me(t),t.length===0)return n(e);let r=e;for(let o=0;o<t.length-1;o++){let i=t[o];if(x(r)){let l=+i;r=r[l]}else if(C(r))r=r[i];else if(h(r)){let l=+i;r=T(r,l)}else if(R(r)){if(o===t.length-2)break;let u=+i,d=+t[++o]==0?"key":"value",y=T(r,u);switch(d){case"key":r=y;break;case"value":r=r.get(y);break}}}let s=t[t.length-1];if(x(r)?r[+s]=n(r[+s]):C(r)&&(r[s]=n(r[s])),h(r)){let o=T(r,+s),i=n(o);o!==i&&(r.delete(o),r.add(i))}if(R(r)){let o=+t[t.length-2],i=T(r,o);switch(+s==0?"key":"value"){case"key":{let u=n(i);r.set(u,r.get(i)),u!==i&&r.delete(i);break}case"value":{r.set(i,n(r.get(i)));break}}}return e};function X(e,t,n=[]){if(!e)return;if(!x(e)){w(e,(o,i)=>X(o,t,[...n,...E(i)]));return}let[r,s]=e;s&&w(s,(o,i)=>{X(o,t,[...n,...E(i)])}),t(r,n)}function Se(e,t,n){return X(t,(r,s)=>{e=V(e,s,o=>ye(o,r,n))}),e}function Oe(e,t){function n(r,s){let o=xe(e,E(s));r.map(E).forEach(i=>{e=V(e,i,()=>o)})}if(x(t)){let[r,s]=t;r.forEach(o=>{e=V(e,E(o),()=>e)}),s&&w(s,n)}else w(t,n);return e}var Ve=(e,t)=>C(e)||x(e)||R(e)||h(e)||G(e,t);function Ue(e,t,n){let r=n.get(e);r?r.push(t):n.set(e,[t])}function ge(e,t){let n={},r;return e.forEach(s=>{if(s.length<=1)return;t||(s=s.map(l=>l.map(String)).sort((l,u)=>l.length-u.length));let[o,...i]=s;o.length===0?r=i.map(K):n[K(o)]=i.map(K)}),r?_(n)?[r]:[r,n]:_(n)?void 0:n}var Q=(e,t,n,r,s=[],o=[],i=new Map)=>{let l=re(e);if(!l){Ue(e,s,t);let m=i.get(e);if(m)return r?{transformedValue:null}:m}if(!Ve(e,n)){let m=F(e,n),f=m?{transformedValue:m.value,annotations:[m.type]}:{transformedValue:e};return l||i.set(e,f),f}if(A(o,e))return{transformedValue:null};let u=F(e,n),d=u?.value??e,y=x(d)?[]:{},g={};w(d,(m,f)=>{if(f==="__proto__"||f==="constructor"||f==="prototype")throw new Error(`Detected property ${f}. This is a prototype pollution risk, please remove it from your object.`);let p=Q(m,t,n,r,[...s,f],[...o,e],i);y[f]=p.transformedValue,x(p.annotations)?g[f]=p.annotations:C(p.annotations)&&w(p.annotations,(Ae,Ee)=>{g[j(f)+"."+Ee]=Ae})});let S=_(g)?{transformedValue:y,annotations:u?[u.type]:void 0}:{transformedValue:y,annotations:u?[u.type,g]:g};return l||i.set(e,S),S};function U(e){return Object.prototype.toString.call(e).slice(8,-1)}function Y(e){return U(e)==="Array"}function Re(e){if(U(e)!=="Object")return!1;let t=Object.getPrototypeOf(e);return!!t&&t.constructor===Object&&t===Object.prototype}function ze(e){return U(e)==="Null"}function De(e,t,n,r,s){return o=>e(o)||t(o)||!!n&&n(o)||!!r&&r(o)||!!s&&s(o)}function Be(e){return U(e)==="Undefined"}var Vt=De(ze,Be);function Le(e,t,n,r,s){let o={}.propertyIsEnumerable.call(r,t)?"enumerable":"nonenumerable";o==="enumerable"&&(e[t]=n),s&&o==="nonenumerable"&&Object.defineProperty(e,t,{value:n,enumerable:!1,writable:!0,configurable:!0})}function z(e,t={}){if(Y(e))return e.map(s=>z(s,t));if(!Re(e))return e;let n=Object.getOwnPropertyNames(e),r=Object.getOwnPropertySymbols(e);return[...n,...r].reduce((s,o)=>{if(Y(t.props)&&!t.props.includes(o))return s;let i=e[o],l=z(i,t);return Le(s,o,l,e,t.nonenumerable),s},{})}var a=class{constructor({dedupe:t=!1}={}){this.classRegistry=new I,this.symbolRegistry=new b(n=>n.description??""),this.customTransformerRegistry=new N,this.allowedErrorProps=[],this.dedupe=t}serialize(t){let n=new Map,r=Q(t,n,this,this.dedupe),s={json:r.transformedValue};r.annotations&&(s.meta={...s.meta,values:r.annotations});let o=ge(n,this.dedupe);return o&&(s.meta={...s.meta,referentialEqualities:o}),s}deserialize(t){let{json:n,meta:r}=t,s=z(n);return r?.values&&(s=Se(s,r.values,this)),r?.referentialEqualities&&(s=Oe(s,r.referentialEqualities)),s}stringify(t){return JSON.stringify(this.serialize(t))}parse(t){return this.deserialize(JSON.parse(t))}registerClass(t,n){this.classRegistry.register(t,n)}registerSymbol(t,n){this.symbolRegistry.register(t,n)}registerCustom(t,n){this.customTransformerRegistry.register({name:n,...t})}allowErrorProps(...t){this.allowedErrorProps.push(...t)}};a.defaultInstance=new a;a.serialize=a.defaultInstance.serialize.bind(a.defaultInstance);a.deserialize=a.defaultInstance.deserialize.bind(a.defaultInstance);a.stringify=a.defaultInstance.stringify.bind(a.defaultInstance);a.parse=a.defaultInstance.parse.bind(a.defaultInstance);a.registerClass=a.defaultInstance.registerClass.bind(a.defaultInstance);a.registerSymbol=a.defaultInstance.registerSymbol.bind(a.defaultInstance);a.registerCustom=a.defaultInstance.registerCustom.bind(a.defaultInstance);a.allowErrorProps=a.defaultInstance.allowErrorProps.bind(a.defaultInstance);var Gt=a.serialize,Ft=a.deserialize,q=a.stringify,k=a.parse,Xt=a.registerClass,W=a.registerCustom,Qt=a.registerSymbol,Yt=a.allowErrorProps;var ve=()=>W({isApplicable:e=>e?.constructor?.name==="Buffer",serialize:e=>q(new Uint8Array(e)),deserialize:e=>k(e)},"buffer"),$e=()=>W({isApplicable:e=>e!==null&&typeof e=="object"&&typeof Reflect.get(e,"s")=="number"&&typeof Reflect.get(e,"e")=="number"&&typeof Reflect.get(e,"toFixed")=="function"&&Array.isArray(Reflect.get(e,"d")),serialize:e=>{throw new Error("Decimal is not yet supported")},deserialize:e=>{new Error("Decimal is not yet supported")}},"decimaljs"),H=()=>{ve(),$e()};var je=c.tuple([c.literal("GET").describe("kind"),c.string().min(1).describe("model")]),Ge=c.enum(["findMany","findFirst","count","findFirstOrThrow","findUnique","findUniqueOrThrow","create","update","delete","upsert","createMany","updateMany","deleteMany","createManyAndReturn","updateManyAndReturn","aggregate","groupBy"]),Fe=c.tuple([c.literal("GET").describe("kind"),Ge]),Xe=c.tuple([c.literal("CALL").describe("kind"),c.array(c.unknown()).readonly().describe("args")]),Qe=c.tuple([c.literal("WAIT").describe("kind")]),Ye=c.tuple([c.literal("COMMIT_ITX").describe("kind")]),We=c.tuple([c.literal("ROLLBACK_ITX").describe("kind")]),He=c.tuple([je,Fe,Xe.describe("args"),Qe.describe("then")]),Ze=c.tuple([Ye]),Je=c.tuple([We]),et=c.union([He,Ze,Je]),tn=c.object({kind:c.literal("SEQUENCE_REQUEST"),globalContext:c.unknown().nullish(),uuid:c.string().min(1),sequence:et,version:c.string().nullish()});var nn=Symbol("SequenceResponse");H();var Z="SEQUENCE_REQUEST",tt="wss://rules-dispatcher.datacdn.workers.dev/",he=3e4,nt=15e3;function D(e){return new Proxy(()=>{},{apply:ot(e),get:ut(e)})}function we(e){return{kind:Z,uuid:crypto.randomUUID(),sequence:[...e?.sequence??[]],globalContext:e?.globalContext}}async function rt({ws:e,args:t}){let{url:n,searchParams:r}=e.args,[s,...o]=t,i=crypto.randomUUID(),l=Ce({url:n,searchParams:{...r,itx:JSON.stringify(t)}}),u=s(D({ws:l}));return u.then(()=>l.send({kind:Z,uuid:i,sequence:[["COMMIT_ITX"]]})).catch(()=>l.send({kind:Z,uuid:i,sequence:[["ROLLBACK_ITX"]]})),await u}async function st(){throw new Error("Batch transactions are not yet supported")}function ot({ws:e,...t}){return(n,r,s)=>{if(t.prop==="$transaction")return typeof s[0]=="function"?rt({ws:e,args:s}):st();let o=we(t.payload);return o.sequence.push(["CALL",s]),D({ws:e,payload:o})}}function it({ws:e,payload:t,prop:n}){t.sequence.push(["WAIT"]);let r=e.send(t);return r[n].bind(r)}function at(e){return{setGlobalContext(t){be=t}}}function ut({ws:e,...t}){return(n,r)=>{let s=we(t.payload);if(r==="then"||r==="catch"||r==="finally")return it({ws:e,payload:s,prop:r});if(r==="$rules")return at({ws:e,payload:s,prop:r});if(s.sequence.push(["GET",r]),ct(s.sequence))throw new Error("Model field references are not yet supported");return D({...t,ws:e,payload:s,prop:r})}}function ct(e){return e[0]?.[0]==="GET"&&e[1]?.[0]==="GET"&&e[1]?.[1]==="fields"}function Ce(e={}){let t={},{url:n=tt,searchParams:r={}}=e,s;async function o(){if(s===void 0)return await i();let{ws:u,date:d}=s;return u===void 0||Date.now()-d>=nt?(setTimeout(()=>u?.close(),he),await i()):{ws:u,date:d}}async function i(u=0){let d=await new Promise((y,g)=>{let S=new WebSocket(`${n}?${new URLSearchParams(r).toString()}`),m=Date.now();S.addEventListener("error",()=>g()),S.addEventListener("open",()=>y({ws:S,date:m})),S.addEventListener("close",()=>delete d.ws),S.addEventListener("message",({data:f})=>{let p=k(f);p.kind==="SEQUENCE_RESPONSE_ALLOW"&&t[p.uuid]?.resolve(p.result),p.kind==="SEQUENCE_RESPONSE_DENY"&&t[p.uuid]?.reject(new Error(p.reason)),p.kind==="SEQUENCE_RESPONSE_ERROR"&&t[p.uuid]?.reject(new Error(p.reason)),p.uuid&&delete t[p.uuid]})}).catch(async()=>(await new Promise(y=>setTimeout(y,1e3*u)),console.warn("Failed to connect to the server, retrying..."),await i(u+1)));return s=d}async function l(u){let d,y=new Promise((...f)=>d=f),[g,S]=d;u.globalContext=be,t[u.uuid]={resolve:g,reject:S},(await o()).ws.send(q(u));let m=setTimeout(()=>{t[u.uuid]?.reject(new Error("Operation timed out")),delete t[u.uuid]},he);return await y.finally(()=>clearTimeout(m))}return{send:l,args:e}}function lt(e){let{url:t,publicKey:n}=e;return D({ws:Ce({url:t,searchParams:{publicKey:n}})})}var be,pt=lt;export{pt as AuthorizedClient,Te as defineRules};
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prisma/security-rules",
|
|
3
|
+
"version": "0.0.0-dev.202504071300",
|
|
4
|
+
"sideEffects": false,
|
|
5
|
+
"description": "Prisma Postgres Security Rules",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"keywords": [],
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@standard-schema/spec": "1.0.0",
|
|
19
|
+
"superjson": "2.2.2"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@prisma/client": "6.2.1",
|
|
23
|
+
"npm-run-all": "4.1.5",
|
|
24
|
+
"prisma": "6.2.1",
|
|
25
|
+
"tsup": "8.0.2",
|
|
26
|
+
"tsx": "4.17.0",
|
|
27
|
+
"typescript": "5.5.4",
|
|
28
|
+
"vitest": "1.5.3",
|
|
29
|
+
"wrangler": "3.105.1",
|
|
30
|
+
"zod": "3.24.1"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@prisma/client": ">=6.2.0",
|
|
34
|
+
"arktype": ">=2.0.0",
|
|
35
|
+
"effect": ">=3.13.0",
|
|
36
|
+
"zod": ">=3.24.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependenciesMeta": {
|
|
39
|
+
"arktype": {
|
|
40
|
+
"optional": true
|
|
41
|
+
},
|
|
42
|
+
"effect": {
|
|
43
|
+
"optional": true
|
|
44
|
+
},
|
|
45
|
+
"zod": {
|
|
46
|
+
"optional": true
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=22"
|
|
51
|
+
},
|
|
52
|
+
"files": [
|
|
53
|
+
"assets",
|
|
54
|
+
"dist"
|
|
55
|
+
],
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "tsup",
|
|
58
|
+
"typecheck": "tsc --noEmit",
|
|
59
|
+
"lint": "eslint --fix .",
|
|
60
|
+
"test": ""
|
|
61
|
+
}
|
|
62
|
+
}
|