on-zero 0.0.87 → 0.0.88
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/dist/cjs/createZeroClient.cjs +32 -15
- package/dist/cjs/createZeroClient.js +42 -20
- package/dist/cjs/createZeroClient.js.map +1 -1
- package/dist/cjs/createZeroClient.native.js +61 -25
- package/dist/cjs/createZeroClient.native.js.map +1 -1
- package/dist/cjs/createZeroServer.cjs +3 -3
- package/dist/cjs/createZeroServer.js +2 -2
- package/dist/cjs/createZeroServer.js.map +1 -1
- package/dist/cjs/createZeroServer.native.js +3 -3
- package/dist/cjs/createZeroServer.native.js.map +1 -1
- package/dist/cjs/modelRegistry.cjs +4 -0
- package/dist/cjs/modelRegistry.js +4 -0
- package/dist/cjs/modelRegistry.js.map +1 -1
- package/dist/cjs/modelRegistry.native.js +4 -0
- package/dist/cjs/modelRegistry.native.js.map +1 -1
- package/dist/cjs/where.cjs +6 -1
- package/dist/cjs/where.js +6 -1
- package/dist/cjs/where.js.map +1 -1
- package/dist/cjs/where.native.js +7 -2
- package/dist/cjs/where.native.js.map +1 -1
- package/dist/esm/createZeroClient.js +44 -22
- package/dist/esm/createZeroClient.js.map +1 -1
- package/dist/esm/createZeroClient.mjs +34 -17
- package/dist/esm/createZeroClient.mjs.map +1 -1
- package/dist/esm/createZeroClient.native.js +63 -27
- package/dist/esm/createZeroClient.native.js.map +1 -1
- package/dist/esm/createZeroServer.js +2 -2
- package/dist/esm/createZeroServer.js.map +1 -1
- package/dist/esm/createZeroServer.mjs +3 -3
- package/dist/esm/createZeroServer.mjs.map +1 -1
- package/dist/esm/createZeroServer.native.js +3 -3
- package/dist/esm/createZeroServer.native.js.map +1 -1
- package/dist/esm/modelRegistry.js +4 -0
- package/dist/esm/modelRegistry.js.map +1 -1
- package/dist/esm/modelRegistry.mjs +4 -1
- package/dist/esm/modelRegistry.mjs.map +1 -1
- package/dist/esm/modelRegistry.native.js +4 -1
- package/dist/esm/modelRegistry.native.js.map +1 -1
- package/dist/esm/where.js +6 -1
- package/dist/esm/where.js.map +1 -1
- package/dist/esm/where.mjs +6 -2
- package/dist/esm/where.mjs.map +1 -1
- package/dist/esm/where.native.js +6 -2
- package/dist/esm/where.native.js.map +1 -1
- package/package.json +1 -1
- package/src/createZeroClient.tsx +80 -37
- package/src/createZeroServer.ts +4 -4
- package/src/modelRegistry.ts +4 -0
- package/src/where.ts +9 -1
- package/types/createZeroClient.d.ts +3 -1
- package/types/createZeroClient.d.ts.map +1 -1
- package/types/modelRegistry.d.ts +1 -0
- package/types/modelRegistry.d.ts.map +1 -1
- package/types/where.d.ts +1 -0
- package/types/where.d.ts.map +1 -1
package/dist/esm/where.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { isServer } from "./constants";
|
|
2
2
|
import { getQueryOrMutatorAuthData } from "./helpers/getQueryOrMutatorAuthData";
|
|
3
|
+
let _evaluatingPermission = !1;
|
|
4
|
+
function setEvaluatingPermission(value) {
|
|
5
|
+
_evaluatingPermission = value;
|
|
6
|
+
}
|
|
3
7
|
function where(a, b, isServerOnly = !1) {
|
|
4
8
|
const whereFn = b || a, wrappedWhereFn = ((a2, b2 = getQueryOrMutatorAuthData()) => {
|
|
5
|
-
if (!isServer && isServerOnly)
|
|
9
|
+
if (!isServer && isServerOnly && !_evaluatingPermission)
|
|
6
10
|
return a2.and();
|
|
7
11
|
const result = whereFn(a2, b2);
|
|
8
12
|
return typeof result == "boolean" ? result ? a2.cmpLit(0, "=", 0) : a2.cmpLit(1, "=", 0) : result;
|
|
@@ -19,6 +23,7 @@ function getRawWhere(where2) {
|
|
|
19
23
|
export {
|
|
20
24
|
getRawWhere,
|
|
21
25
|
getWhereTableName,
|
|
26
|
+
setEvaluatingPermission,
|
|
22
27
|
where
|
|
23
28
|
};
|
|
24
29
|
//# sourceMappingURL=where.js.map
|
package/dist/esm/where.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/where.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAS,iCAAiC;
|
|
4
|
+
"mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAS,iCAAiC;AAO1C,IAAI,wBAAwB;AAErB,SAAS,wBAAwB,OAAgB;AACtD,0BAAwB;AAC1B;AAYO,SAAS,MACd,GACA,GACA,eAAe,IACc;AAC7B,QAAM,UAAW,KAAK,GAEhB,kBAAkB,CACtBA,IACAC,KAAI,0BAA0B,MAC3B;AACH,QAAI,CAAC,YAAY,gBAAgB,CAAC;AAEhC,aAAOD,GAAE,IAAI;AAGf,UAAM,SAAS,QAAQA,IAAGC,EAAC;AAC3B,WAAI,OAAO,UAAW,YAChB,SACKD,GAAE,OAAO,GAAG,KAAK,CAAC,IAElBA,GAAE,OAAO,GAAG,KAAK,CAAC,IAGtB;AAAA,EACT;AAGA,4BAAmB,IAAI,gBAAgB,OAAO,GAE1C,KACF,kBAAkB,IAAI,gBAAgB,CAAU,GAG3C;AACT;AAIA,MAAM,oBAAoB,oBAAI,QAA0B,GAClD,qBAAqB,oBAAI,QAAsB;AAE9C,SAAS,kBAAkBE,QAAc;AAC9C,SAAO,kBAAkB,IAAIA,MAAK;AACpC;AAGO,SAAS,YAAYA,QAAiC;AAC3D,SAAO,mBAAmB,IAAIA,MAAK;AACrC;",
|
|
5
5
|
"names": ["a", "b", "where"]
|
|
6
6
|
}
|
package/dist/esm/where.mjs
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { isServer } from "./constants.mjs";
|
|
2
2
|
import { getQueryOrMutatorAuthData } from "./helpers/getQueryOrMutatorAuthData.mjs";
|
|
3
|
+
let _evaluatingPermission = !1;
|
|
4
|
+
function setEvaluatingPermission(value) {
|
|
5
|
+
_evaluatingPermission = value;
|
|
6
|
+
}
|
|
3
7
|
function where(a, b, isServerOnly = !1) {
|
|
4
8
|
const whereFn = b || a,
|
|
5
9
|
wrappedWhereFn = (a2, b2 = getQueryOrMutatorAuthData()) => {
|
|
6
|
-
if (!isServer && isServerOnly) return a2.and();
|
|
10
|
+
if (!isServer && isServerOnly && !_evaluatingPermission) return a2.and();
|
|
7
11
|
const result = whereFn(a2, b2);
|
|
8
12
|
return typeof result == "boolean" ? result ? a2.cmpLit(0, "=", 0) : a2.cmpLit(1, "=", 0) : result;
|
|
9
13
|
};
|
|
@@ -17,5 +21,5 @@ function getWhereTableName(where2) {
|
|
|
17
21
|
function getRawWhere(where2) {
|
|
18
22
|
return WhereRawBuilderMap.get(where2);
|
|
19
23
|
}
|
|
20
|
-
export { getRawWhere, getWhereTableName, where };
|
|
24
|
+
export { getRawWhere, getWhereTableName, setEvaluatingPermission, where };
|
|
21
25
|
//# sourceMappingURL=where.mjs.map
|
package/dist/esm/where.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["isServer","getQueryOrMutatorAuthData","where","a","b","isServerOnly","whereFn","wrappedWhereFn","a2","b2","and","result","cmpLit","WhereRawBuilderMap","set","WhereTableNameMap","WeakMap","getWhereTableName","where2","get","getRawWhere"],"sources":["../../src/where.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,QAAgB;AACzB,SAASC,yBAAA,QAAiC;
|
|
1
|
+
{"version":3,"names":["isServer","getQueryOrMutatorAuthData","_evaluatingPermission","setEvaluatingPermission","value","where","a","b","isServerOnly","whereFn","wrappedWhereFn","a2","b2","and","result","cmpLit","WhereRawBuilderMap","set","WhereTableNameMap","WeakMap","getWhereTableName","where2","get","getRawWhere"],"sources":["../../src/where.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,QAAgB;AACzB,SAASC,yBAAA,QAAiC;AAO1C,IAAIC,qBAAA,GAAwB;AAErB,SAASC,wBAAwBC,KAAA,EAAgB;EACtDF,qBAAA,GAAwBE,KAAA;AAC1B;AAYO,SAASC,MACdC,CAAA,EACAC,CAAA,EACAC,YAAA,GAAe,IACc;EAC7B,MAAMC,OAAA,GAAWF,CAAA,IAAKD,CAAA;IAEhBI,cAAA,GAAkBA,CACtBC,EAAA,EACAC,EAAA,GAAIX,yBAAA,CAA0B,MAC3B;MACH,IAAI,CAACD,QAAA,IAAYQ,YAAA,IAAgB,CAACN,qBAAA,EAEhC,OAAOS,EAAA,CAAEE,GAAA,CAAI;MAGf,MAAMC,MAAA,GAASL,OAAA,CAAQE,EAAA,EAAGC,EAAC;MAC3B,OAAI,OAAOE,MAAA,IAAW,YAChBA,MAAA,GACKH,EAAA,CAAEI,MAAA,CAAO,GAAG,KAAK,CAAC,IAElBJ,EAAA,CAAEI,MAAA,CAAO,GAAG,KAAK,CAAC,IAGtBD,MAAA;IACT;EAGA,OAAAE,kBAAA,CAAmBC,GAAA,CAAIP,cAAA,EAAgBD,OAAO,GAE1CF,CAAA,IACFW,iBAAA,CAAkBD,GAAA,CAAIP,cAAA,EAAgBJ,CAAU,GAG3CI,cAAA;AACT;AAIA,MAAMQ,iBAAA,GAAoB,mBAAIC,OAAA,CAA0B;EAClDH,kBAAA,GAAqB,mBAAIG,OAAA,CAAsB;AAE9C,SAASC,kBAAkBC,MAAA,EAAc;EAC9C,OAAOH,iBAAA,CAAkBI,GAAA,CAAID,MAAK;AACpC;AAGO,SAASE,YAAYF,MAAA,EAAiC;EAC3D,OAAOL,kBAAA,CAAmBM,GAAA,CAAID,MAAK;AACrC","ignoreList":[]}
|
package/dist/esm/where.native.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { isServer } from "./constants.native.js";
|
|
2
2
|
import { getQueryOrMutatorAuthData } from "./helpers/getQueryOrMutatorAuthData.native.js";
|
|
3
|
+
var _evaluatingPermission = !1;
|
|
4
|
+
function setEvaluatingPermission(value) {
|
|
5
|
+
_evaluatingPermission = value;
|
|
6
|
+
}
|
|
3
7
|
function where(a, b) {
|
|
4
8
|
var isServerOnly = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : !1,
|
|
5
9
|
whereFn = b || a,
|
|
6
10
|
wrappedWhereFn = function (a2) {
|
|
7
11
|
var _$b = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : getQueryOrMutatorAuthData();
|
|
8
|
-
if (!isServer && isServerOnly) return a2.and();
|
|
12
|
+
if (!isServer && isServerOnly && !_evaluatingPermission) return a2.and();
|
|
9
13
|
var result = whereFn(a2, _$b);
|
|
10
14
|
return typeof result == "boolean" ? result ? a2.cmpLit(0, "=", 0) : a2.cmpLit(1, "=", 0) : result;
|
|
11
15
|
};
|
|
@@ -19,5 +23,5 @@ function getWhereTableName(where2) {
|
|
|
19
23
|
function getRawWhere(where2) {
|
|
20
24
|
return WhereRawBuilderMap.get(where2);
|
|
21
25
|
}
|
|
22
|
-
export { getRawWhere, getWhereTableName, where };
|
|
26
|
+
export { getRawWhere, getWhereTableName, setEvaluatingPermission, where };
|
|
23
27
|
//# sourceMappingURL=where.native.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["isServer","getQueryOrMutatorAuthData","where","a","b","isServerOnly","arguments","length","whereFn","wrappedWhereFn","a2","_$b","and","result","cmpLit","WhereRawBuilderMap","set","WhereTableNameMap","WeakMap","getWhereTableName","where2","get","getRawWhere"],"sources":["../../src/where.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,QAAgB;AACzB,SAASC,yBAAA,QAAiC;
|
|
1
|
+
{"version":3,"names":["isServer","getQueryOrMutatorAuthData","_evaluatingPermission","setEvaluatingPermission","value","where","a","b","isServerOnly","arguments","length","whereFn","wrappedWhereFn","a2","_$b","and","result","cmpLit","WhereRawBuilderMap","set","WhereTableNameMap","WeakMap","getWhereTableName","where2","get","getRawWhere"],"sources":["../../src/where.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,QAAgB;AACzB,SAASC,yBAAA,QAAiC;AAO1C,IAAIC,qBAAA,GAAwB;AAErB,SAASC,wBAAwBC,KAAA,EAAgB;EACtDF,qBAAA,GAAwBE,KAAA;AAC1B;AAYO,SAASC,MACdC,CAAA,EACAC,CAAA,EACA;EAEA,IAAAC,YAAiB,GAAAC,SAEX,CAAAC,MAAA,QACJD,SACI,iBAAAA,SAA0B,MAC3B;IAAAE,OAAA,GAAAJ,CAAA,IAAAD,CAAA;IAAAM,cAAA,YAAAA,CAAAC,EAAA;MACH,IAAIC,GAAC,GAAAL,SAAY,CAAAC,MAAA,QAAiBD,SAAA,iBAAAA,SAAA,MAAAR,yBAAA;MAEhC,KAAAD,QAAS,IAAIQ,YAAA,KAAAN,qBAAA,EAGf,OAAMW,EAAA,CAAAE,GAAS;MACf,IAAAC,MAAI,GAAAL,OAAO,CAAAE,EAAA,EAAWC,GAAA;MAQxB,cAAAE,MAAA,gBAAAA,MAAA,GAAAH,EAAA,CAAAI,MAAA,cAAAJ,EAAA,CAAAI,MAAA,cAAAD,MAAA;IAGA;EAOF,OAAAE,kBAAA,CAAAC,GAAA,CAAAP,cAAA,EAAAD,OAAA,GAAAJ,CAAA,IAAAa,iBAAA,CAAAD,GAAA,CAAAP,cAAA,EAAAN,CAAA,GAAAM,cAAA;AAIA;AAGO,IAAAQ,iBAAS,kBAAgC,IAAAC,OAAA;EAAAH,kBAAA,sBAAAG,OAAA;AAC9C,SAAOC,kBAAkBC,MAAI;EAC/B,OAAAH,iBAAA,CAAAI,GAAA,CAAAD,MAAA;AAGO;AACL,SAAOE,YAAAF,MAAA,EAAmB;EAC5B,OAAAL,kBAAA,CAAAM,GAAA,CAAAD,MAAA","ignoreList":[]}
|
package/package.json
CHANGED
package/src/createZeroClient.tsx
CHANGED
|
@@ -15,12 +15,12 @@ import { createPermissions } from './createPermissions'
|
|
|
15
15
|
import { createUseQuery } from './createUseQuery'
|
|
16
16
|
import { createMutators } from './helpers/createMutators'
|
|
17
17
|
import { getQueryOrMutatorAuthData } from './helpers/getQueryOrMutatorAuthData'
|
|
18
|
-
import { getMutationsPermissions } from './modelRegistry'
|
|
18
|
+
import { getAllMutationsPermissions, getMutationsPermissions } from './modelRegistry'
|
|
19
19
|
import { registerQuery } from './queryRegistry'
|
|
20
20
|
import { resolveQuery, type PlainQueryFn } from './resolveQuery'
|
|
21
21
|
import { setCustomQueries } from './run'
|
|
22
22
|
import { setAuthData, setSchema } from './state'
|
|
23
|
-
import { getRawWhere } from './where'
|
|
23
|
+
import { getRawWhere, setEvaluatingPermission } from './where'
|
|
24
24
|
import { setRunner } from './zeroRunner'
|
|
25
25
|
import { zql } from './zql'
|
|
26
26
|
|
|
@@ -31,6 +31,12 @@ type PreloadOptions = { ttl?: 'always' | 'never' | number | undefined }
|
|
|
31
31
|
|
|
32
32
|
export type GroupedQueries = Record<string, Record<string, (...args: any[]) => any>>
|
|
33
33
|
|
|
34
|
+
// controls how usePermission behaves before the server responds:
|
|
35
|
+
// - 'optimistic': evaluate the permission query on the client (default)
|
|
36
|
+
// - 'optimistic-deny': return false until server confirms
|
|
37
|
+
// - 'optimistic-allow': return true until server confirms
|
|
38
|
+
export type PermissionStrategy = 'optimistic' | 'optimistic-deny' | 'optimistic-allow'
|
|
39
|
+
|
|
34
40
|
export function createZeroClient<
|
|
35
41
|
Schema extends ZeroSchema,
|
|
36
42
|
Models extends GenericModels,
|
|
@@ -38,10 +44,12 @@ export function createZeroClient<
|
|
|
38
44
|
schema,
|
|
39
45
|
models,
|
|
40
46
|
groupedQueries,
|
|
47
|
+
permissionStrategy = 'optimistic',
|
|
41
48
|
}: {
|
|
42
49
|
schema: Schema
|
|
43
50
|
models: Models
|
|
44
51
|
groupedQueries: GroupedQueries
|
|
52
|
+
permissionStrategy?: PermissionStrategy
|
|
45
53
|
}) {
|
|
46
54
|
type ZeroMutators = GetZeroMutators<Models>
|
|
47
55
|
type ZeroInstance = Zero<Schema, ZeroMutators>
|
|
@@ -74,41 +82,74 @@ export function createZeroClient<
|
|
|
74
82
|
}
|
|
75
83
|
}
|
|
76
84
|
|
|
77
|
-
// register permission
|
|
78
|
-
// client: evaluates raw permission condition for optimistic result
|
|
85
|
+
// register per-model permission queries so each table gets its own materialized view
|
|
86
|
+
// client: evaluates raw permission condition for optimistic result
|
|
79
87
|
// server: evaluates real permission condition authoritatively
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
objOrId: string | Record<string, any>
|
|
83
|
-
|
|
84
|
-
const perm = getMutationsPermissions(args.table)
|
|
85
|
-
const base = (zql as any)[args.table]
|
|
88
|
+
const permissionCheckFns: Record<
|
|
89
|
+
string,
|
|
90
|
+
(args: { objOrId: string | Record<string, any> }) => any
|
|
91
|
+
> = {}
|
|
86
92
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
93
|
+
const createPermissionCheckFn = (table: string) => {
|
|
94
|
+
const fn = (args: { objOrId: string | Record<string, any> }) => {
|
|
95
|
+
const perm = getMutationsPermissions(table)
|
|
96
|
+
const base = (zql as any)[table]
|
|
91
97
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
98
|
+
if (!args.objOrId) {
|
|
99
|
+
return base.where((eb: any) => eb.cmpLit(true, '=', false)).one()
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (permissionStrategy === 'optimistic') {
|
|
103
|
+
// unwrap serverWhere so conditions actually evaluate on client
|
|
104
|
+
// set flag so nested serverWhere calls also bypass the client no-op
|
|
105
|
+
const rawPerm = perm ? getRawWhere(perm) || perm : perm
|
|
106
|
+
return base
|
|
107
|
+
.where((eb: any) => {
|
|
108
|
+
setEvaluatingPermission(true)
|
|
109
|
+
try {
|
|
110
|
+
return permissionsHelpers.buildPermissionQuery(
|
|
111
|
+
getQueryOrMutatorAuthData(),
|
|
112
|
+
eb,
|
|
113
|
+
rawPerm || ((e: any) => e.and()),
|
|
114
|
+
args.objOrId,
|
|
115
|
+
table
|
|
116
|
+
)
|
|
117
|
+
} finally {
|
|
118
|
+
setEvaluatingPermission(false)
|
|
119
|
+
}
|
|
120
|
+
})
|
|
121
|
+
.one()
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (permissionStrategy === 'optimistic-deny') {
|
|
125
|
+
// client query always returns false, server corrects authoritatively
|
|
126
|
+
return base.where((eb: any) => eb.cmpLit(true, '=', false)).one()
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// optimistic-allow: pass wrapped perm directly
|
|
130
|
+
// serverWhere is a no-op on client → eb.and() → always true → row exists check
|
|
131
|
+
// server evaluates real condition and corrects authoritatively
|
|
132
|
+
return base
|
|
133
|
+
.where((eb: any) => {
|
|
134
|
+
return permissionsHelpers.buildPermissionQuery(
|
|
135
|
+
getQueryOrMutatorAuthData(),
|
|
136
|
+
eb,
|
|
137
|
+
perm || ((e: any) => e.and()),
|
|
138
|
+
args.objOrId,
|
|
139
|
+
table
|
|
140
|
+
)
|
|
141
|
+
})
|
|
142
|
+
.one()
|
|
143
|
+
}
|
|
144
|
+
permissionCheckFns[table] = fn
|
|
145
|
+
registerQuery(fn, `permission.${table}`)
|
|
146
|
+
return fn
|
|
107
147
|
}
|
|
108
148
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
149
|
+
wrappedNamespaces['permission'] = {}
|
|
150
|
+
for (const [table] of getAllMutationsPermissions()) {
|
|
151
|
+
const fn = createPermissionCheckFn(table)
|
|
152
|
+
wrappedNamespaces['permission'][table] = defineQuery(({ args }: any) => fn(args))
|
|
112
153
|
}
|
|
113
154
|
|
|
114
155
|
// create the single shared CustomQuery registry
|
|
@@ -143,8 +184,8 @@ export function createZeroClient<
|
|
|
143
184
|
customQueries,
|
|
144
185
|
})
|
|
145
186
|
|
|
146
|
-
// permission check uses a synced query so server is authoritative
|
|
147
|
-
//
|
|
187
|
+
// permission check uses a per-model synced query so server is authoritative
|
|
188
|
+
// permissionStrategy controls client behavior before server responds
|
|
148
189
|
function usePermission(
|
|
149
190
|
table: TableName | (string & {}),
|
|
150
191
|
objOrId: string | Partial<Row<any>> | undefined,
|
|
@@ -152,11 +193,13 @@ export function createZeroClient<
|
|
|
152
193
|
debug = false
|
|
153
194
|
): boolean | null {
|
|
154
195
|
const disabled = use(DisabledContext)
|
|
196
|
+
const tableStr = table as string
|
|
197
|
+
const checkFn = permissionCheckFns[tableStr]
|
|
155
198
|
|
|
156
199
|
const [data, status] = useQuery(
|
|
157
|
-
|
|
158
|
-
{
|
|
159
|
-
{ enabled: Boolean(!disabled && enabled && objOrId) }
|
|
200
|
+
checkFn as any,
|
|
201
|
+
{ objOrId: objOrId as any },
|
|
202
|
+
{ enabled: Boolean(!disabled && enabled && objOrId && checkFn) }
|
|
160
203
|
)
|
|
161
204
|
|
|
162
205
|
if (debug) {
|
package/src/createZeroServer.ts
CHANGED
|
@@ -132,10 +132,10 @@ export function createZeroServer<
|
|
|
132
132
|
|
|
133
133
|
const response = await zeroHandleQueryRequest(
|
|
134
134
|
(name, args) => {
|
|
135
|
-
// permission
|
|
136
|
-
if (name
|
|
137
|
-
const
|
|
138
|
-
|
|
135
|
+
// per-model permission queries registered by on-zero at runtime
|
|
136
|
+
if (name.startsWith('permission.')) {
|
|
137
|
+
const table = name.slice('permission.'.length)
|
|
138
|
+
const { objOrId } = args as {
|
|
139
139
|
objOrId: string | Record<string, any>
|
|
140
140
|
}
|
|
141
141
|
const perm = getMutationsPermissions(table)
|
package/src/modelRegistry.ts
CHANGED
|
@@ -9,3 +9,7 @@ export function setMutationsPermissions(tableName: string, permissions: Where) {
|
|
|
9
9
|
export function getMutationsPermissions(tableName: string): Where | undefined {
|
|
10
10
|
return mutationsToPermissionsRegistry.get(tableName)
|
|
11
11
|
}
|
|
12
|
+
|
|
13
|
+
export function getAllMutationsPermissions(): Map<string, Where> {
|
|
14
|
+
return mutationsToPermissionsRegistry
|
|
15
|
+
}
|
package/src/where.ts
CHANGED
|
@@ -4,6 +4,14 @@ import { getQueryOrMutatorAuthData } from './helpers/getQueryOrMutatorAuthData'
|
|
|
4
4
|
import type { TableName, Where } from './types'
|
|
5
5
|
import type { Condition, ExpressionBuilder } from '@rocicorp/zero'
|
|
6
6
|
|
|
7
|
+
// when true, serverWhere bypasses the client no-op so nested serverWhere
|
|
8
|
+
// calls inside permission builders actually evaluate on the client
|
|
9
|
+
let _evaluatingPermission = false
|
|
10
|
+
|
|
11
|
+
export function setEvaluatingPermission(value: boolean) {
|
|
12
|
+
_evaluatingPermission = value
|
|
13
|
+
}
|
|
14
|
+
|
|
7
15
|
export function where<Table extends TableName, Builder extends Where<Table>>(
|
|
8
16
|
tableName: Table,
|
|
9
17
|
builder: Builder,
|
|
@@ -25,7 +33,7 @@ export function where<Table extends TableName, Builder extends Where<Table>>(
|
|
|
25
33
|
a: ExpressionBuilder<any, any>,
|
|
26
34
|
b = getQueryOrMutatorAuthData()
|
|
27
35
|
) => {
|
|
28
|
-
if (!isServer && isServerOnly) {
|
|
36
|
+
if (!isServer && isServerOnly && !_evaluatingPermission) {
|
|
29
37
|
// on client (web or native) where conditions always pass
|
|
30
38
|
return a.and()
|
|
31
39
|
}
|
|
@@ -6,10 +6,12 @@ type PreloadOptions = {
|
|
|
6
6
|
ttl?: 'always' | 'never' | number | undefined;
|
|
7
7
|
};
|
|
8
8
|
export type GroupedQueries = Record<string, Record<string, (...args: any[]) => any>>;
|
|
9
|
-
export
|
|
9
|
+
export type PermissionStrategy = 'optimistic' | 'optimistic-deny' | 'optimistic-allow';
|
|
10
|
+
export declare function createZeroClient<Schema extends ZeroSchema, Models extends GenericModels>({ schema, models, groupedQueries, permissionStrategy, }: {
|
|
10
11
|
schema: Schema;
|
|
11
12
|
models: Models;
|
|
12
13
|
groupedQueries: GroupedQueries;
|
|
14
|
+
permissionStrategy?: PermissionStrategy;
|
|
13
15
|
}): {
|
|
14
16
|
zeroEvents: import("@take-out/helpers").Emitter<ZeroEvent | null>;
|
|
15
17
|
ProvideZero: ({ children, authData: authDataIn, disable, ...props }: Omit<ZeroOptions<Schema, GetZeroMutators<Models>>, "schema" | "mutators"> & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createZeroClient.d.ts","sourceRoot":"","sources":["../src/createZeroClient.tsx"],"names":[],"mappings":"AAGA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAA;AAQd,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAOhE,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAClF,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEzF,KAAK,cAAc,GAAG;IAAE,GAAG,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAEvE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"createZeroClient.d.ts","sourceRoot":"","sources":["../src/createZeroClient.tsx"],"names":[],"mappings":"AAGA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAA;AAQd,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAOhE,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAClF,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEzF,KAAK,cAAc,GAAG;IAAE,GAAG,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAEvE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;AAMpF,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,iBAAiB,GAAG,kBAAkB,CAAA;AAEtF,wBAAgB,gBAAgB,CAC9B,MAAM,SAAS,UAAU,EACzB,MAAM,SAAS,aAAa,EAC5B,EACA,MAAM,EACN,MAAM,EACN,cAAc,EACd,kBAAiC,GAClC,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,cAAc,CAAA;IAC9B,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;CACxC;;yEAyKI,IAAI,CAAC,WAAW,CAAC,MAAM,0BAAe,EAAE,QAAQ,GAAG,UAAU,CAAC,GAAG;QAClE,QAAQ,EAAE,SAAS,CAAA;QACnB,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;QAC1B,OAAO,CAAC,EAAE,OAAO,CAAA;KAClB;;2BApCQ,yJAAY,CAAC,MAAM,GAAG,EAAE,CAAC,WACvB,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,yCAG9C,OAAO,GAAG,IAAI;;;SA0HA,IAAI,EAAE,MAAM,SAAS,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,OAAO,MACxE,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,UAC9C,IAAI,YACF,cAAc,GACvB;YAAE,OAAO,EAAE,MAAM,IAAI,CAAC;YAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;SAAE;SAClC,MAAM,SAAS,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,OAAO,MAClE,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,YAC5C,cAAc,GACvB;YAAE,OAAO,EAAE,MAAM,IAAI,CAAC;YAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;SAAE;;EAuBpD"}
|
package/types/modelRegistry.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Where } from './types';
|
|
2
2
|
export declare function setMutationsPermissions(tableName: string, permissions: Where): void;
|
|
3
3
|
export declare function getMutationsPermissions(tableName: string): Where | undefined;
|
|
4
|
+
export declare function getAllMutationsPermissions(): Map<string, Where>;
|
|
4
5
|
//# sourceMappingURL=modelRegistry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modelRegistry.d.ts","sourceRoot":"","sources":["../src/modelRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAI/B,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,QAE5E;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAE5E"}
|
|
1
|
+
{"version":3,"file":"modelRegistry.d.ts","sourceRoot":"","sources":["../src/modelRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAI/B,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,QAE5E;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAE5E;AAED,wBAAgB,0BAA0B,IAAI,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAE/D"}
|
package/types/where.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { TableName, Where } from './types';
|
|
2
2
|
import type { Condition } from '@rocicorp/zero';
|
|
3
|
+
export declare function setEvaluatingPermission(value: boolean): void;
|
|
3
4
|
export declare function where<Table extends TableName, Builder extends Where<Table>>(tableName: Table, builder: Builder, isServerOnly?: boolean): Where<Table, Condition>;
|
|
4
5
|
export declare function where<Table extends TableName, Builder extends Where = Where<Table>>(builder: Builder): Where<Table, Condition>;
|
|
5
6
|
export declare function getWhereTableName(where: Where): string | undefined;
|
package/types/where.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"where.d.ts","sourceRoot":"","sources":["../src/where.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAqB,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"where.d.ts","sourceRoot":"","sources":["../src/where.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAqB,MAAM,gBAAgB,CAAA;AAMlE,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,QAErD;AAED,wBAAgB,KAAK,CAAC,KAAK,SAAS,SAAS,EAAE,OAAO,SAAS,KAAK,CAAC,KAAK,CAAC,EACzE,SAAS,EAAE,KAAK,EAChB,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,OAAO,GACrB,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;AAE1B,wBAAgB,KAAK,CAAC,KAAK,SAAS,SAAS,EAAE,OAAO,SAAS,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,EACjF,OAAO,EAAE,OAAO,GACf,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;AA4C1B,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,sBAE7C;AAGD,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CAE3D"}
|