@api-client/core 0.18.58 → 0.18.60
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/build/src/decorators/observed.d.ts.map +1 -1
- package/build/src/decorators/observed.js +15 -1
- package/build/src/decorators/observed.js.map +1 -1
- package/build/src/modeling/ApiModel.d.ts.map +1 -1
- package/build/src/modeling/ApiModel.js +2 -2
- package/build/src/modeling/ApiModel.js.map +1 -1
- package/build/src/modeling/ExposedEntity.d.ts.map +1 -1
- package/build/src/modeling/ExposedEntity.js +4 -4
- package/build/src/modeling/ExposedEntity.js.map +1 -1
- package/build/src/modeling/actions/Action.d.ts.map +1 -1
- package/build/src/modeling/actions/Action.js +2 -2
- package/build/src/modeling/actions/Action.js.map +1 -1
- package/build/src/modeling/actions/CreateAction.d.ts +2 -0
- package/build/src/modeling/actions/CreateAction.d.ts.map +1 -1
- package/build/src/modeling/actions/CreateAction.js +6 -0
- package/build/src/modeling/actions/CreateAction.js.map +1 -1
- package/build/src/modeling/actions/DeleteAction.d.ts +2 -0
- package/build/src/modeling/actions/DeleteAction.d.ts.map +1 -1
- package/build/src/modeling/actions/DeleteAction.js +6 -0
- package/build/src/modeling/actions/DeleteAction.js.map +1 -1
- package/build/src/modeling/actions/ListAction.d.ts +2 -0
- package/build/src/modeling/actions/ListAction.d.ts.map +1 -1
- package/build/src/modeling/actions/ListAction.js +8 -2
- package/build/src/modeling/actions/ListAction.js.map +1 -1
- package/build/src/modeling/actions/ReadAction.d.ts +2 -0
- package/build/src/modeling/actions/ReadAction.d.ts.map +1 -1
- package/build/src/modeling/actions/ReadAction.js +6 -0
- package/build/src/modeling/actions/ReadAction.js.map +1 -1
- package/build/src/modeling/actions/SearchAction.d.ts +2 -0
- package/build/src/modeling/actions/SearchAction.d.ts.map +1 -1
- package/build/src/modeling/actions/SearchAction.js +6 -0
- package/build/src/modeling/actions/SearchAction.js.map +1 -1
- package/build/src/modeling/actions/UpdateAction.d.ts +2 -0
- package/build/src/modeling/actions/UpdateAction.d.ts.map +1 -1
- package/build/src/modeling/actions/UpdateAction.js +6 -0
- package/build/src/modeling/actions/UpdateAction.js.map +1 -1
- package/build/src/modeling/actions/index.d.ts +10 -0
- package/build/src/modeling/actions/index.d.ts.map +1 -1
- package/build/src/modeling/actions/index.js +30 -0
- package/build/src/modeling/actions/index.js.map +1 -1
- package/build/src/modeling/rules/AllowAuthenticated.d.ts +2 -2
- package/build/src/modeling/rules/AllowAuthenticated.d.ts.map +1 -1
- package/build/src/modeling/rules/AllowAuthenticated.js +1 -1
- package/build/src/modeling/rules/AllowAuthenticated.js.map +1 -1
- package/build/src/modeling/rules/AllowPublic.d.ts +2 -2
- package/build/src/modeling/rules/AllowPublic.d.ts.map +1 -1
- package/build/src/modeling/rules/AllowPublic.js +1 -1
- package/build/src/modeling/rules/AllowPublic.js.map +1 -1
- package/build/src/modeling/rules/MatchResourceOwner.d.ts +2 -2
- package/build/src/modeling/rules/MatchResourceOwner.d.ts.map +1 -1
- package/build/src/modeling/rules/MatchResourceOwner.js +1 -1
- package/build/src/modeling/rules/MatchResourceOwner.js.map +1 -1
- package/build/src/modeling/rules/index.d.ts +14 -2
- package/build/src/modeling/rules/index.d.ts.map +1 -1
- package/build/src/modeling/rules/index.js +32 -1
- package/build/src/modeling/rules/index.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/data/models/example-generator-api.json +25 -25
- package/package.json +1 -1
- package/src/decorators/observed.ts +15 -1
- package/src/modeling/ApiModel.ts +2 -1
- package/src/modeling/ExposedEntity.ts +4 -2
- package/src/modeling/actions/Action.ts +2 -1
- package/src/modeling/actions/CreateAction.ts +8 -0
- package/src/modeling/actions/DeleteAction.ts +8 -0
- package/src/modeling/actions/ListAction.ts +10 -2
- package/src/modeling/actions/ReadAction.ts +8 -0
- package/src/modeling/actions/SearchAction.ts +8 -0
- package/src/modeling/actions/UpdateAction.ts +8 -0
- package/src/modeling/rules/AllowAuthenticated.ts +3 -3
- package/src/modeling/rules/AllowPublic.ts +3 -3
- package/src/modeling/rules/MatchResourceOwner.ts +3 -3
- package/tests/unit/decorators/observed.spec.ts +42 -0
- package/tests/unit/modeling/actions/Action.spec.ts +10 -10
- package/tests/unit/modeling/actions/CreateAction.spec.ts +8 -8
- package/tests/unit/modeling/actions/DeleteAction.spec.ts +5 -5
- package/tests/unit/modeling/actions/ReadAction.spec.ts +9 -9
- package/tests/unit/modeling/api_model.spec.ts +3 -3
- package/tests/unit/modeling/exposed_entity.spec.ts +8 -8
- package/tests/unit/modeling/exposed_entity_actions.spec.ts +182 -0
- package/tests/unit/modeling/rules/AllowAuthenticated.spec.ts +2 -2
- package/tests/unit/modeling/rules/AllowPublic.spec.ts +2 -2
- package/tests/unit/modeling/rules/MatchResourceOwner.spec.ts +3 -3
- package/tests/unit/modeling/rules/restoring_rules.spec.ts +121 -0
|
@@ -42062,9 +42062,6 @@
|
|
|
42062
42062
|
"@id": "#209"
|
|
42063
42063
|
},
|
|
42064
42064
|
{
|
|
42065
|
-
"@id": "#206"
|
|
42066
|
-
},
|
|
42067
|
-
{
|
|
42068
42065
|
"@id": "#191"
|
|
42069
42066
|
},
|
|
42070
42067
|
{
|
|
@@ -42074,10 +42071,13 @@
|
|
|
42074
42071
|
"@id": "#197"
|
|
42075
42072
|
},
|
|
42076
42073
|
{
|
|
42074
|
+
"@id": "#203"
|
|
42075
|
+
},
|
|
42076
|
+
{
|
|
42077
42077
|
"@id": "#200"
|
|
42078
42078
|
},
|
|
42079
42079
|
{
|
|
42080
|
-
"@id": "#
|
|
42080
|
+
"@id": "#206"
|
|
42081
42081
|
},
|
|
42082
42082
|
{
|
|
42083
42083
|
"@id": "#209"
|
|
@@ -42810,16 +42810,16 @@
|
|
|
42810
42810
|
"@id": "#219"
|
|
42811
42811
|
},
|
|
42812
42812
|
{
|
|
42813
|
-
"@id": "#
|
|
42813
|
+
"@id": "#210"
|
|
42814
42814
|
},
|
|
42815
42815
|
{
|
|
42816
|
-
"@id": "#
|
|
42816
|
+
"@id": "#219"
|
|
42817
42817
|
},
|
|
42818
42818
|
{
|
|
42819
|
-
"@id": "#
|
|
42819
|
+
"@id": "#213"
|
|
42820
42820
|
},
|
|
42821
42821
|
{
|
|
42822
|
-
"@id": "#
|
|
42822
|
+
"@id": "#216"
|
|
42823
42823
|
}
|
|
42824
42824
|
],
|
|
42825
42825
|
"doc:root": false,
|
|
@@ -43436,7 +43436,7 @@
|
|
|
43436
43436
|
"doc:ExternalDomainElement",
|
|
43437
43437
|
"doc:DomainElement"
|
|
43438
43438
|
],
|
|
43439
|
-
"doc:raw": "
|
|
43439
|
+
"doc:raw": "countryCode: \"BE\"\ngraydonEnterpriseId: 1057155523\nregistrationId: \"0422319093\"\nvatNumber: \"BE0422319093\"\ngraydonCompanyId: \"0422319093\"\nisBranchOffice: false\n",
|
|
43440
43440
|
"core:mediaType": "application/yaml",
|
|
43441
43441
|
"sourcemaps:sources": [
|
|
43442
43442
|
{
|
|
@@ -43457,7 +43457,7 @@
|
|
|
43457
43457
|
"doc:ExternalDomainElement",
|
|
43458
43458
|
"doc:DomainElement"
|
|
43459
43459
|
],
|
|
43460
|
-
"doc:raw": "
|
|
43460
|
+
"doc:raw": "addressType: 'REGISTERED-OFFICE-ADDRESS'\nstreetName: 'UITBREIDINGSTRAAT'\nhouseNumber: '84'\nhouseNumberAddition: '/1'\npostalCode: '2600'\ncity: 'BERCHEM (ANTWERPEN)'\ncountry: 'Belgium'\ncountryCode: 'BE'\nfullFormatedAddress: \"UITBREIDINGSTRAAT 84 /1, 2600 BERCHEM (ANTWERPEN), BELIUM\"\n",
|
|
43461
43461
|
"core:mediaType": "application/yaml",
|
|
43462
43462
|
"sourcemaps:sources": [
|
|
43463
43463
|
{
|
|
@@ -43478,7 +43478,7 @@
|
|
|
43478
43478
|
"doc:ExternalDomainElement",
|
|
43479
43479
|
"doc:DomainElement"
|
|
43480
43480
|
],
|
|
43481
|
-
"doc:raw": "
|
|
43481
|
+
"doc:raw": "code: '5'\ndescription: 'Limited company'\n",
|
|
43482
43482
|
"core:mediaType": "application/yaml",
|
|
43483
43483
|
"sourcemaps:sources": [
|
|
43484
43484
|
{
|
|
@@ -43520,7 +43520,7 @@
|
|
|
43520
43520
|
"doc:ExternalDomainElement",
|
|
43521
43521
|
"doc:DomainElement"
|
|
43522
43522
|
],
|
|
43523
|
-
"doc:raw": "
|
|
43523
|
+
"doc:raw": "class: '3'\ndescription: '150 - 300'\nnumberOfFte: 5500\nnumberOfEmployees: 5232\n",
|
|
43524
43524
|
"core:mediaType": "application/yaml",
|
|
43525
43525
|
"sourcemaps:sources": [
|
|
43526
43526
|
{
|
|
@@ -43541,7 +43541,7 @@
|
|
|
43541
43541
|
"doc:ExternalDomainElement",
|
|
43542
43542
|
"doc:DomainElement"
|
|
43543
43543
|
],
|
|
43544
|
-
"doc:raw": "
|
|
43544
|
+
"doc:raw": "code: '7487'\ndescription: 'Financial and insurance activities'\ntype: \"PRIMARY\"\nclassificationCode: 'BE_NACEBEL2008'\nactivityGroupCode: 'ABCDE'\n",
|
|
43545
43545
|
"core:mediaType": "application/yaml",
|
|
43546
43546
|
"sourcemaps:sources": [
|
|
43547
43547
|
{
|
|
@@ -44232,7 +44232,7 @@
|
|
|
44232
44232
|
"doc:ExternalDomainElement",
|
|
44233
44233
|
"doc:DomainElement"
|
|
44234
44234
|
],
|
|
44235
|
-
"doc:raw": "
|
|
44235
|
+
"doc:raw": "type: 'GENERAL'\ncountryDialCode : '+32'\nareaCode : '22'\nsubscriberNumber: '12.87.00'\nformatted: '+32-(0)22 000000'\n",
|
|
44236
44236
|
"core:mediaType": "application/yaml",
|
|
44237
44237
|
"sourcemaps:sources": [
|
|
44238
44238
|
{
|
|
@@ -44253,7 +44253,7 @@
|
|
|
44253
44253
|
"doc:ExternalDomainElement",
|
|
44254
44254
|
"doc:DomainElement"
|
|
44255
44255
|
],
|
|
44256
|
-
"doc:raw": "type:
|
|
44256
|
+
"doc:raw": "-\n type: 'GENERAL'\n value: 'info@company.be'\n-\n type: 'IT_DEPT'\n value: 'it-service@company.be'\n",
|
|
44257
44257
|
"core:mediaType": "application/yaml",
|
|
44258
44258
|
"sourcemaps:sources": [
|
|
44259
44259
|
{
|
|
@@ -44274,7 +44274,7 @@
|
|
|
44274
44274
|
"doc:ExternalDomainElement",
|
|
44275
44275
|
"doc:DomainElement"
|
|
44276
44276
|
],
|
|
44277
|
-
"doc:raw": "type:
|
|
44277
|
+
"doc:raw": "type: \"GENERAL\"\nvalue: \"www.company.be\"\n",
|
|
44278
44278
|
"core:mediaType": "application/yaml",
|
|
44279
44279
|
"sourcemaps:sources": [
|
|
44280
44280
|
{
|
|
@@ -44295,7 +44295,7 @@
|
|
|
44295
44295
|
"doc:ExternalDomainElement",
|
|
44296
44296
|
"doc:DomainElement"
|
|
44297
44297
|
],
|
|
44298
|
-
"doc:raw": "type: 'GENERAL'\ncountryDialCode : '+32'\nareaCode : '
|
|
44298
|
+
"doc:raw": "type: 'GENERAL'\ncountryDialCode : '+32'\nareaCode : '21'\nsubscriberNumber: '12.87.00'\nformatted: '+32-(0)21 302099'\n",
|
|
44299
44299
|
"core:mediaType": "application/yaml",
|
|
44300
44300
|
"sourcemaps:sources": [
|
|
44301
44301
|
{
|
|
@@ -44756,17 +44756,17 @@
|
|
|
44756
44756
|
{
|
|
44757
44757
|
"@id": "#193/source-map/lexical/element_0",
|
|
44758
44758
|
"sourcemaps:element": "amf://id#193",
|
|
44759
|
-
"sourcemaps:value": "[(1,0)-(
|
|
44759
|
+
"sourcemaps:value": "[(1,0)-(7,0)]"
|
|
44760
44760
|
},
|
|
44761
44761
|
{
|
|
44762
44762
|
"@id": "#196/source-map/lexical/element_0",
|
|
44763
44763
|
"sourcemaps:element": "amf://id#196",
|
|
44764
|
-
"sourcemaps:value": "[(1,0)-(
|
|
44764
|
+
"sourcemaps:value": "[(1,0)-(10,0)]"
|
|
44765
44765
|
},
|
|
44766
44766
|
{
|
|
44767
44767
|
"@id": "#199/source-map/lexical/element_0",
|
|
44768
44768
|
"sourcemaps:element": "amf://id#199",
|
|
44769
|
-
"sourcemaps:value": "[(1,0)-(
|
|
44769
|
+
"sourcemaps:value": "[(1,0)-(3,0)]"
|
|
44770
44770
|
},
|
|
44771
44771
|
{
|
|
44772
44772
|
"@id": "#202/source-map/lexical/element_0",
|
|
@@ -44776,12 +44776,12 @@
|
|
|
44776
44776
|
{
|
|
44777
44777
|
"@id": "#205/source-map/lexical/element_0",
|
|
44778
44778
|
"sourcemaps:element": "amf://id#205",
|
|
44779
|
-
"sourcemaps:value": "[(1,0)-(
|
|
44779
|
+
"sourcemaps:value": "[(1,0)-(5,0)]"
|
|
44780
44780
|
},
|
|
44781
44781
|
{
|
|
44782
44782
|
"@id": "#208/source-map/lexical/element_0",
|
|
44783
44783
|
"sourcemaps:element": "amf://id#208",
|
|
44784
|
-
"sourcemaps:value": "[(1,0)-(
|
|
44784
|
+
"sourcemaps:value": "[(1,0)-(6,0)]"
|
|
44785
44785
|
},
|
|
44786
44786
|
{
|
|
44787
44787
|
"@id": "#223/source-map/lexical/element_0",
|
|
@@ -45116,17 +45116,17 @@
|
|
|
45116
45116
|
{
|
|
45117
45117
|
"@id": "#212/source-map/lexical/element_0",
|
|
45118
45118
|
"sourcemaps:element": "amf://id#212",
|
|
45119
|
-
"sourcemaps:value": "[(1,0)-(
|
|
45119
|
+
"sourcemaps:value": "[(1,0)-(6,0)]"
|
|
45120
45120
|
},
|
|
45121
45121
|
{
|
|
45122
45122
|
"@id": "#215/source-map/lexical/element_0",
|
|
45123
45123
|
"sourcemaps:element": "amf://id#215",
|
|
45124
|
-
"sourcemaps:value": "[(1,0)-(
|
|
45124
|
+
"sourcemaps:value": "[(1,0)-(7,0)]"
|
|
45125
45125
|
},
|
|
45126
45126
|
{
|
|
45127
45127
|
"@id": "#218/source-map/lexical/element_0",
|
|
45128
45128
|
"sourcemaps:element": "amf://id#218",
|
|
45129
|
-
"sourcemaps:value": "[(1,0)-(
|
|
45129
|
+
"sourcemaps:value": "[(1,0)-(3,0)]"
|
|
45130
45130
|
},
|
|
45131
45131
|
{
|
|
45132
45132
|
"@id": "#221/source-map/lexical/element_0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
const reactiveSymbol = Symbol('reactive')
|
|
3
3
|
const proxySymbol = Symbol('proxy')
|
|
4
|
+
const rawSymbol = Symbol('raw')
|
|
4
5
|
|
|
5
6
|
interface DomainInstance {
|
|
6
7
|
domain?: { notifyChange(): void }
|
|
@@ -38,6 +39,13 @@ export interface ObserveConfig {
|
|
|
38
39
|
* @returns The not proxied object or undefined
|
|
39
40
|
*/
|
|
40
41
|
export function toRaw<T extends object = object>(source: object, target: T): T | undefined {
|
|
42
|
+
if (target && (target as any)[rawSymbol]) {
|
|
43
|
+
let raw = (target as any)[rawSymbol]
|
|
44
|
+
while (raw && (raw as any)[rawSymbol]) {
|
|
45
|
+
raw = (raw as any)[rawSymbol]
|
|
46
|
+
}
|
|
47
|
+
return raw as T
|
|
48
|
+
}
|
|
41
49
|
const proxies = Reflect.get(source, proxySymbol) as Map<object, object>
|
|
42
50
|
if (!proxies) {
|
|
43
51
|
return undefined
|
|
@@ -101,7 +109,7 @@ export function observed(config: ObserveConfig = {}): PropertyDecorator {
|
|
|
101
109
|
}
|
|
102
110
|
|
|
103
111
|
if (proxies.has(obj)) {
|
|
104
|
-
return obj
|
|
112
|
+
return proxies.get(obj)
|
|
105
113
|
}
|
|
106
114
|
|
|
107
115
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
@@ -109,6 +117,12 @@ export function observed(config: ObserveConfig = {}): PropertyDecorator {
|
|
|
109
117
|
|
|
110
118
|
const proxy = new Proxy(obj, {
|
|
111
119
|
get(target, prop) {
|
|
120
|
+
if (prop === proxySymbol) {
|
|
121
|
+
return Reflect.get(target, prop)
|
|
122
|
+
}
|
|
123
|
+
if (prop === rawSymbol) {
|
|
124
|
+
return target
|
|
125
|
+
}
|
|
112
126
|
const value = Reflect.get(target, prop)
|
|
113
127
|
return createDeepProxy.bind(targetObject)(value, notifyChange)
|
|
114
128
|
},
|
package/src/modeling/ApiModel.ts
CHANGED
|
@@ -19,6 +19,7 @@ import { createDomainKey } from './helpers/keying.js'
|
|
|
19
19
|
import { ExposedEntity } from './ExposedEntity.js'
|
|
20
20
|
import { AccessRule, AccessRuleSchema } from './rules/AccessRule.js'
|
|
21
21
|
import { RateLimitingConfiguration, RateLimitingConfigurationSchema } from './rules/RateLimitingConfiguration.js'
|
|
22
|
+
import { restoreAccessRule } from './rules/index.js'
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Contact information for the exposed API.
|
|
@@ -310,7 +311,7 @@ export class ApiModel extends DependentModel {
|
|
|
310
311
|
this.exposes = []
|
|
311
312
|
}
|
|
312
313
|
if (Array.isArray(init.accessRule)) {
|
|
313
|
-
this.accessRule = init.accessRule.map((rule) =>
|
|
314
|
+
this.accessRule = init.accessRule.map((rule) => restoreAccessRule(rule))
|
|
314
315
|
} else {
|
|
315
316
|
this.accessRule = []
|
|
316
317
|
}
|
|
@@ -2,9 +2,11 @@ import { observed } from '../decorators/observed.js'
|
|
|
2
2
|
import { ExposedEntityKind } from '../models/kinds.js'
|
|
3
3
|
import { nanoid } from '../nanoid.js'
|
|
4
4
|
import { Action } from './actions/Action.js'
|
|
5
|
+
import { restoreAction } from './actions/index.js'
|
|
5
6
|
import type { ApiModel } from './ApiModel.js'
|
|
6
7
|
import { ensureLeadingSlash, joinPaths } from './helpers/endpointHelpers.js'
|
|
7
8
|
import { AccessRule } from './rules/AccessRule.js'
|
|
9
|
+
import { restoreAccessRule } from './rules/index.js'
|
|
8
10
|
import { RateLimitingConfiguration } from './rules/RateLimitingConfiguration.js'
|
|
9
11
|
import type { AssociationTarget, ExposeOptions, ExposeParentRef, ExposedEntitySchema } from './types.js'
|
|
10
12
|
|
|
@@ -182,8 +184,8 @@ export class ExposedEntity extends EventTarget {
|
|
|
182
184
|
this.isRoot = init.isRoot
|
|
183
185
|
this.parent = init.parent
|
|
184
186
|
this.exposeOptions = init.exposeOptions
|
|
185
|
-
this.actions = init.actions ? init.actions.map((a) =>
|
|
186
|
-
this.accessRule = init.accessRule ? init.accessRule.map((ar) =>
|
|
187
|
+
this.actions = init.actions ? init.actions.map((a) => restoreAction(a)) : []
|
|
188
|
+
this.accessRule = init.accessRule ? init.accessRule.map((ar) => restoreAccessRule(ar)) : []
|
|
187
189
|
this.rateLimiting = init.rateLimiting ? new RateLimitingConfiguration(init.rateLimiting) : undefined
|
|
188
190
|
this.truncated = init.truncated
|
|
189
191
|
this.#initializing = false
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AccessRule, AccessRuleSchema } from '../rules/AccessRule.js'
|
|
2
2
|
import { RateLimitingConfiguration, RateLimitingConfigurationSchema } from '../rules/RateLimitingConfiguration.js'
|
|
3
3
|
import { observed } from '../../decorators/observed.js'
|
|
4
|
+
import { restoreAccessRule } from '../rules/index.js'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* A base interface for common properties across all actions.
|
|
@@ -41,7 +42,7 @@ export class Action extends EventTarget implements ActionSchema {
|
|
|
41
42
|
constructor(state: Partial<ActionSchema> = {}) {
|
|
42
43
|
super()
|
|
43
44
|
this.kind = state.kind || ''
|
|
44
|
-
this.accessRule = state.accessRule ? state.accessRule.map((rule) =>
|
|
45
|
+
this.accessRule = state.accessRule ? state.accessRule.map((rule) => restoreAccessRule(rule)) : []
|
|
45
46
|
this.rateLimiting = state.rateLimiting ? new RateLimitingConfiguration(state.rateLimiting) : undefined
|
|
46
47
|
}
|
|
47
48
|
|
|
@@ -27,4 +27,12 @@ export class CreateAction extends Action implements CreateActionSchema {
|
|
|
27
27
|
kind: 'create',
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
+
|
|
31
|
+
static isCreateAction(action: Action): action is CreateAction {
|
|
32
|
+
return action.kind === 'create'
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static isCreateActionSchema(schema: ActionSchema): schema is CreateActionSchema {
|
|
36
|
+
return schema.kind === 'create'
|
|
37
|
+
}
|
|
30
38
|
}
|
|
@@ -48,4 +48,12 @@ export class DeleteAction extends Action implements DeleteActionSchema {
|
|
|
48
48
|
retentionPeriod: this.retentionPeriod,
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
+
|
|
52
|
+
static isDeleteAction(action: Action): action is DeleteAction {
|
|
53
|
+
return action.kind === 'delete'
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static isDeleteActionSchema(schema: ActionSchema): schema is DeleteActionSchema {
|
|
57
|
+
return schema.kind === 'delete'
|
|
58
|
+
}
|
|
51
59
|
}
|
|
@@ -32,8 +32,8 @@ export interface ListActionSchema extends ActionSchema {
|
|
|
32
32
|
export class ListAction extends Action implements ListActionSchema {
|
|
33
33
|
@observed() override accessor kind: 'list'
|
|
34
34
|
@observed({ deep: true }) accessor pagination: PaginationStrategy
|
|
35
|
-
@observed({ deep: true }) accessor filterableFields: string[]
|
|
36
|
-
@observed({ deep: true }) accessor sortableFields: string[]
|
|
35
|
+
@observed({ deep: true }) accessor filterableFields: string[] = []
|
|
36
|
+
@observed({ deep: true }) accessor sortableFields: string[] = []
|
|
37
37
|
|
|
38
38
|
constructor(state: Partial<ListActionSchema> = {}) {
|
|
39
39
|
super(state)
|
|
@@ -55,4 +55,12 @@ export class ListAction extends Action implements ListActionSchema {
|
|
|
55
55
|
sortableFields: structuredClone(toRaw(this, this.sortableFields)) as string[],
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
+
|
|
59
|
+
static isListAction(action: Action): action is ListAction {
|
|
60
|
+
return action.kind === 'list'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static isListActionSchema(schema: ActionSchema): schema is ListActionSchema {
|
|
64
|
+
return schema.kind === 'list'
|
|
65
|
+
}
|
|
58
66
|
}
|
|
@@ -29,4 +29,12 @@ export class ReadAction extends Action implements ReadActionSchema {
|
|
|
29
29
|
kind: 'read',
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
static isReadAction(action: Action): action is ReadAction {
|
|
34
|
+
return action.kind === 'read'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static isReadActionSchema(schema: ActionSchema): schema is ReadActionSchema {
|
|
38
|
+
return schema.kind === 'read'
|
|
39
|
+
}
|
|
32
40
|
}
|
|
@@ -35,4 +35,12 @@ export class SearchAction extends Action implements SearchActionSchema {
|
|
|
35
35
|
fields: structuredClone(toRaw(this, this.fields)) as string[],
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
static isSearchActionSchema(schema: ActionSchema): schema is SearchActionSchema {
|
|
40
|
+
return schema.kind === 'search'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static isSearchAction(action: Action): action is SearchAction {
|
|
44
|
+
return action.kind === 'search'
|
|
45
|
+
}
|
|
38
46
|
}
|
|
@@ -38,4 +38,12 @@ export class UpdateAction extends Action implements UpdateActionSchema {
|
|
|
38
38
|
allowedMethods: structuredClone(toRaw(this, this.allowedMethods)) as ('PUT' | 'PATCH')[],
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
+
|
|
42
|
+
static isUpdateAction(action: Action): action is UpdateAction {
|
|
43
|
+
return action.kind === 'update'
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static isUpdateActionSchema(schema: ActionSchema): schema is UpdateActionSchema {
|
|
47
|
+
return schema.kind === 'update'
|
|
48
|
+
}
|
|
41
49
|
}
|
|
@@ -6,7 +6,7 @@ import { AccessRule, type AccessRuleSchema } from './AccessRule.js'
|
|
|
6
6
|
* It is used for resources that should be accessible to all logged-in users.
|
|
7
7
|
*/
|
|
8
8
|
export interface AllowAuthenticatedAccessRuleSchema extends AccessRuleSchema {
|
|
9
|
-
type: '
|
|
9
|
+
type: 'allowAuthenticated'
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -15,10 +15,10 @@ export interface AllowAuthenticatedAccessRuleSchema extends AccessRuleSchema {
|
|
|
15
15
|
* It is used for resources that should be accessible to all logged-in users.
|
|
16
16
|
*/
|
|
17
17
|
export class AllowAuthenticatedAccessRule extends AccessRule implements AllowAuthenticatedAccessRuleSchema {
|
|
18
|
-
override readonly type: '
|
|
18
|
+
override readonly type: 'allowAuthenticated'
|
|
19
19
|
|
|
20
20
|
constructor(state: Partial<AllowAuthenticatedAccessRuleSchema> = {}) {
|
|
21
21
|
super(state)
|
|
22
|
-
this.type = '
|
|
22
|
+
this.type = 'allowAuthenticated'
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -6,7 +6,7 @@ import { AccessRule, type AccessRuleSchema } from './AccessRule.js'
|
|
|
6
6
|
* It is the most permissive rule and should be used with caution.
|
|
7
7
|
*/
|
|
8
8
|
export interface AllowPublicAccessRuleSchema extends AccessRuleSchema {
|
|
9
|
-
type: '
|
|
9
|
+
type: 'allowPublic'
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -15,10 +15,10 @@ export interface AllowPublicAccessRuleSchema extends AccessRuleSchema {
|
|
|
15
15
|
* It is the most permissive rule and should be used with caution.
|
|
16
16
|
*/
|
|
17
17
|
export class AllowPublicAccessRule extends AccessRule implements AllowPublicAccessRuleSchema {
|
|
18
|
-
override readonly type: '
|
|
18
|
+
override readonly type: 'allowPublic'
|
|
19
19
|
|
|
20
20
|
constructor(state: Partial<AllowPublicAccessRuleSchema> = {}) {
|
|
21
21
|
super(state)
|
|
22
|
-
this.type = '
|
|
22
|
+
this.type = 'allowPublic'
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -7,7 +7,7 @@ import { observed } from '../../decorators/observed.js'
|
|
|
7
7
|
* For example, a user can only access their own profile or documents.
|
|
8
8
|
*/
|
|
9
9
|
export interface MatchResourceOwnerAccessRuleSchema extends AccessRuleSchema {
|
|
10
|
-
type: '
|
|
10
|
+
type: 'matchResourceOwner'
|
|
11
11
|
/**
|
|
12
12
|
* The property on the resource that should match the authenticated user's ID.
|
|
13
13
|
* This is typically the ID of the user who owns the resource.
|
|
@@ -24,13 +24,13 @@ export interface MatchResourceOwnerAccessRuleSchema extends AccessRuleSchema {
|
|
|
24
24
|
* For example, a user can only access their own profile or documents.
|
|
25
25
|
*/
|
|
26
26
|
export class MatchResourceOwnerAccessRule extends AccessRule implements MatchResourceOwnerAccessRuleSchema {
|
|
27
|
-
override readonly type: '
|
|
27
|
+
override readonly type: 'matchResourceOwner'
|
|
28
28
|
|
|
29
29
|
@observed() accessor property: string
|
|
30
30
|
|
|
31
31
|
constructor(state: Partial<MatchResourceOwnerAccessRuleSchema> = {}) {
|
|
32
32
|
super(state)
|
|
33
|
-
this.type = '
|
|
33
|
+
this.type = 'matchResourceOwner'
|
|
34
34
|
this.property = state.property ?? ''
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -446,6 +446,48 @@ test.group('toRaw function', () => {
|
|
|
446
446
|
const raw = toRaw(instance, obj)
|
|
447
447
|
assert.equal(raw, undefined)
|
|
448
448
|
}).tags(['@decorators', '@toRaw', '@core', '@unit', '@fast'])
|
|
449
|
+
|
|
450
|
+
test('should handle nested deep proxies (regression test)', ({ assert }) => {
|
|
451
|
+
const mockDomain = {
|
|
452
|
+
notifyChange() {},
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
class Child {
|
|
456
|
+
name = 'child'
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
class Parent {
|
|
460
|
+
domain = mockDomain
|
|
461
|
+
@observed({ deep: true }) accessor child: Child
|
|
462
|
+
|
|
463
|
+
constructor() {
|
|
464
|
+
this.child = new Child()
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
class GrandParent {
|
|
469
|
+
domain = mockDomain
|
|
470
|
+
@observed({ deep: true }) accessor parent: Parent
|
|
471
|
+
|
|
472
|
+
constructor() {
|
|
473
|
+
this.parent = new Parent()
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
const gp = new GrandParent()
|
|
478
|
+
// gp.parent is a proxy
|
|
479
|
+
// gp.parent.child is a nested proxy (proxy of a proxy)
|
|
480
|
+
const childProxy = gp.parent.child
|
|
481
|
+
|
|
482
|
+
const raw = toRaw(gp.parent, childProxy)
|
|
483
|
+
|
|
484
|
+
assert.isDefined(raw)
|
|
485
|
+
assert.equal(raw?.name, 'child')
|
|
486
|
+
|
|
487
|
+
// Should be able to structure clone it (proving it's a clean object without proxy wrappers)
|
|
488
|
+
const cloned = structuredClone(raw)
|
|
489
|
+
assert.deepEqual(cloned, { name: 'child' })
|
|
490
|
+
}).tags(['@decorators', '@toRaw', '@core', '@unit', '@regression'])
|
|
449
491
|
})
|
|
450
492
|
|
|
451
493
|
test.group('edge cases and error conditions', () => {
|
|
@@ -13,27 +13,27 @@ test.group('Action', () => {
|
|
|
13
13
|
test('initializes with provided values', ({ assert }) => {
|
|
14
14
|
const schema: ActionSchema = {
|
|
15
15
|
kind: 'read',
|
|
16
|
-
accessRule: [{ type: '
|
|
16
|
+
accessRule: [{ type: 'allowPublic' }],
|
|
17
17
|
rateLimiting: { rules: [] },
|
|
18
18
|
}
|
|
19
19
|
const action = new Action(schema)
|
|
20
20
|
assert.equal(action.kind, 'read')
|
|
21
21
|
assert.lengthOf(action.accessRule, 1)
|
|
22
22
|
assert.instanceOf(action.accessRule[0], AccessRule)
|
|
23
|
-
assert.equal(action.accessRule[0].type, '
|
|
23
|
+
assert.equal(action.accessRule[0].type, 'allowPublic')
|
|
24
24
|
assert.instanceOf(action.rateLimiting, RateLimitingConfiguration)
|
|
25
25
|
}).tags(['@modeling', '@action'])
|
|
26
26
|
|
|
27
27
|
test('serializes to JSON', ({ assert }) => {
|
|
28
28
|
const action = new Action({
|
|
29
29
|
kind: 'write',
|
|
30
|
-
accessRule: [{ type: '
|
|
30
|
+
accessRule: [{ type: 'allowPublic' }],
|
|
31
31
|
rateLimiting: { rules: [] },
|
|
32
32
|
})
|
|
33
33
|
const json = action.toJSON()
|
|
34
34
|
|
|
35
35
|
assert.equal(json.kind, 'write')
|
|
36
|
-
assert.deepEqual(json.accessRule, [{ type: '
|
|
36
|
+
assert.deepEqual(json.accessRule, [{ type: 'allowPublic' }])
|
|
37
37
|
assert.deepEqual(json.rateLimiting, { rules: [] })
|
|
38
38
|
}).tags(['@modeling', '@action'])
|
|
39
39
|
|
|
@@ -58,7 +58,7 @@ test.group('Action', () => {
|
|
|
58
58
|
notified = true
|
|
59
59
|
})
|
|
60
60
|
|
|
61
|
-
action.accessRule = [new AccessRule({ type: '
|
|
61
|
+
action.accessRule = [new AccessRule({ type: 'allowPublic' })]
|
|
62
62
|
await Promise.resolve()
|
|
63
63
|
assert.isTrue(notified)
|
|
64
64
|
}).tags(['@modeling', '@action', '@observed'])
|
|
@@ -76,21 +76,21 @@ test.group('Action', () => {
|
|
|
76
76
|
}).tags(['@modeling', '@action', '@observed'])
|
|
77
77
|
|
|
78
78
|
test('constructor copies accessRule array (immutability)', ({ assert }) => {
|
|
79
|
-
const rules = [{ type: '
|
|
79
|
+
const rules = [{ type: 'allowPublic' }]
|
|
80
80
|
const action = new Action({ kind: 'read', accessRule: rules })
|
|
81
81
|
|
|
82
82
|
// Modify original array
|
|
83
|
-
rules.push({ type: '
|
|
83
|
+
rules.push({ type: 'other' })
|
|
84
84
|
rules[0].type = 'changed'
|
|
85
85
|
|
|
86
86
|
assert.lengthOf(action.accessRule, 1)
|
|
87
|
-
assert.equal(action.accessRule[0].type, '
|
|
87
|
+
assert.equal(action.accessRule[0].type, 'allowPublic')
|
|
88
88
|
}).tags(['@modeling', '@action', '@immutability'])
|
|
89
89
|
|
|
90
90
|
test('toJSON returns safe copy', ({ assert }) => {
|
|
91
91
|
const action = new Action({
|
|
92
92
|
kind: 'read',
|
|
93
|
-
accessRule: [{ type: '
|
|
93
|
+
accessRule: [{ type: 'allowPublic' }],
|
|
94
94
|
rateLimiting: { rules: [] },
|
|
95
95
|
})
|
|
96
96
|
const json = action.toJSON()
|
|
@@ -104,6 +104,6 @@ test.group('Action', () => {
|
|
|
104
104
|
|
|
105
105
|
assert.equal(action.kind, 'read')
|
|
106
106
|
assert.lengthOf(action.accessRule, 1)
|
|
107
|
-
assert.equal(action.accessRule[0].type, '
|
|
107
|
+
assert.equal(action.accessRule[0].type, 'allowPublic')
|
|
108
108
|
}).tags(['@modeling', '@action', '@immutability'])
|
|
109
109
|
})
|
|
@@ -11,32 +11,32 @@ test.group('CreateAction', () => {
|
|
|
11
11
|
|
|
12
12
|
test('initializes with inherited values', ({ assert }) => {
|
|
13
13
|
const action = new CreateAction({
|
|
14
|
-
accessRule: [{ type: '
|
|
14
|
+
accessRule: [{ type: 'allowPublic' }],
|
|
15
15
|
})
|
|
16
16
|
|
|
17
17
|
assert.equal(action.kind, 'create')
|
|
18
18
|
assert.lengthOf(action.accessRule, 1)
|
|
19
|
-
assert.equal(action.accessRule[0].type, '
|
|
19
|
+
assert.equal(action.accessRule[0].type, 'allowPublic')
|
|
20
20
|
}).tags(['@modeling', '@action', '@create-action'])
|
|
21
21
|
|
|
22
22
|
test('constructor copies arrays (immutability)', ({ assert }) => {
|
|
23
|
-
const rules = [{ type: '
|
|
23
|
+
const rules = [{ type: 'allowPublic' }]
|
|
24
24
|
|
|
25
25
|
const action = new CreateAction({
|
|
26
26
|
accessRule: rules,
|
|
27
27
|
})
|
|
28
28
|
|
|
29
29
|
// Modify original source
|
|
30
|
-
rules.push({ type: '
|
|
30
|
+
rules.push({ type: 'other' })
|
|
31
31
|
rules[0].type = 'changed'
|
|
32
32
|
|
|
33
33
|
assert.lengthOf(action.accessRule, 1)
|
|
34
|
-
assert.equal(action.accessRule[0].type, '
|
|
34
|
+
assert.equal(action.accessRule[0].type, 'allowPublic')
|
|
35
35
|
}).tags(['@modeling', '@action', '@create-action', '@immutability'])
|
|
36
36
|
|
|
37
37
|
test('toJSON returns valid schema', ({ assert }) => {
|
|
38
38
|
const action = new CreateAction({
|
|
39
|
-
accessRule: [{ type: '
|
|
39
|
+
accessRule: [{ type: 'allowPublic' }],
|
|
40
40
|
})
|
|
41
41
|
|
|
42
42
|
const json = action.toJSON()
|
|
@@ -44,7 +44,7 @@ test.group('CreateAction', () => {
|
|
|
44
44
|
assert.equal(json.kind, 'create')
|
|
45
45
|
if (json.accessRule) {
|
|
46
46
|
assert.lengthOf(json.accessRule, 1)
|
|
47
|
-
assert.equal(json.accessRule[0].type, '
|
|
47
|
+
assert.equal(json.accessRule[0].type, 'allowPublic')
|
|
48
48
|
} else {
|
|
49
49
|
assert.fail('accessRule should be present in JSON')
|
|
50
50
|
}
|
|
@@ -58,7 +58,7 @@ test.group('CreateAction', () => {
|
|
|
58
58
|
})
|
|
59
59
|
|
|
60
60
|
// Modify inherited property
|
|
61
|
-
action.accessRule = [new AccessRule({ type: '
|
|
61
|
+
action.accessRule = [new AccessRule({ type: 'allowPublic' })]
|
|
62
62
|
await Promise.resolve()
|
|
63
63
|
assert.isTrue(notified)
|
|
64
64
|
}).tags(['@modeling', '@action', '@create-action', '@observed'])
|