@bleedingdev/modern-js-bff-core 3.9.0-ultramodern.4 → 3.9.0-ultramodern.6

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.
Files changed (49) hide show
  1. package/dist/cjs/client/generateClient.js +67 -138
  2. package/dist/cjs/index.js +25 -101
  3. package/dist/esm/client/generateClient.mjs +65 -139
  4. package/dist/esm/index.mjs +0 -4
  5. package/dist/esm-node/client/generateClient.mjs +65 -139
  6. package/dist/esm-node/index.mjs +0 -4
  7. package/dist/types/client/generateClient.d.ts +24 -1
  8. package/dist/types/index.d.ts +0 -4
  9. package/package.json +5 -12
  10. package/dist/cjs/adapter-kit/index.js +0 -144
  11. package/dist/cjs/adapter-kit/parity-scenarios/cross-project-denial.js +0 -55
  12. package/dist/cjs/adapter-kit/parity-scenarios/envelope.js +0 -128
  13. package/dist/cjs/adapter-kit/parity-scenarios/operation-context.js +0 -152
  14. package/dist/cjs/adapter-kit/parity-scenarios/schema.js +0 -109
  15. package/dist/cjs/adapter-kit/parity-scenarios/shared.js +0 -71
  16. package/dist/cjs/adapter-kit/parity.js +0 -204
  17. package/dist/cjs/security/crossProjectPolicy.js +0 -309
  18. package/dist/cjs/security/operationContracts.js +0 -183
  19. package/dist/cjs/security/resolveCrossProjectPolicy.js +0 -65
  20. package/dist/esm/adapter-kit/index.mjs +0 -79
  21. package/dist/esm/adapter-kit/parity-scenarios/cross-project-denial.mjs +0 -17
  22. package/dist/esm/adapter-kit/parity-scenarios/envelope.mjs +0 -90
  23. package/dist/esm/adapter-kit/parity-scenarios/operation-context.mjs +0 -111
  24. package/dist/esm/adapter-kit/parity-scenarios/schema.mjs +0 -71
  25. package/dist/esm/adapter-kit/parity-scenarios/shared.mjs +0 -21
  26. package/dist/esm/adapter-kit/parity.mjs +0 -148
  27. package/dist/esm/security/crossProjectPolicy.mjs +0 -259
  28. package/dist/esm/security/operationContracts.mjs +0 -127
  29. package/dist/esm/security/resolveCrossProjectPolicy.mjs +0 -27
  30. package/dist/esm-node/adapter-kit/index.mjs +0 -80
  31. package/dist/esm-node/adapter-kit/parity-scenarios/cross-project-denial.mjs +0 -18
  32. package/dist/esm-node/adapter-kit/parity-scenarios/envelope.mjs +0 -91
  33. package/dist/esm-node/adapter-kit/parity-scenarios/operation-context.mjs +0 -112
  34. package/dist/esm-node/adapter-kit/parity-scenarios/schema.mjs +0 -72
  35. package/dist/esm-node/adapter-kit/parity-scenarios/shared.mjs +0 -22
  36. package/dist/esm-node/adapter-kit/parity.mjs +0 -149
  37. package/dist/esm-node/security/crossProjectPolicy.mjs +0 -260
  38. package/dist/esm-node/security/operationContracts.mjs +0 -130
  39. package/dist/esm-node/security/resolveCrossProjectPolicy.mjs +0 -28
  40. package/dist/types/adapter-kit/index.d.ts +0 -90
  41. package/dist/types/adapter-kit/parity-scenarios/cross-project-denial.d.ts +0 -2
  42. package/dist/types/adapter-kit/parity-scenarios/envelope.d.ts +0 -2
  43. package/dist/types/adapter-kit/parity-scenarios/operation-context.d.ts +0 -3
  44. package/dist/types/adapter-kit/parity-scenarios/schema.d.ts +0 -2
  45. package/dist/types/adapter-kit/parity-scenarios/shared.d.ts +0 -32
  46. package/dist/types/adapter-kit/parity.d.ts +0 -43
  47. package/dist/types/security/crossProjectPolicy.d.ts +0 -110
  48. package/dist/types/security/operationContracts.d.ts +0 -84
  49. package/dist/types/security/resolveCrossProjectPolicy.d.ts +0 -39
@@ -1,90 +0,0 @@
1
- const createEnvelopeParityScenarios = ()=>[
2
- {
3
- name: 'plain handler returns object payload',
4
- policy: false,
5
- request: {
6
- method: 'get',
7
- path: '/hello'
8
- },
9
- expected: {
10
- kind: 'payload',
11
- status: 200,
12
- payload: {
13
- message: 'hello'
14
- }
15
- }
16
- },
17
- {
18
- name: 'plain handler returns scalar payload',
19
- policy: false,
20
- request: {
21
- method: 'post',
22
- path: '/hello'
23
- },
24
- expected: {
25
- kind: 'payload',
26
- status: 200,
27
- payload: 'hello'
28
- }
29
- },
30
- {
31
- name: 'plain handler returning undefined',
32
- policy: false,
33
- request: {
34
- method: 'get',
35
- path: '/nothing'
36
- },
37
- expected: {
38
- kind: 'payload',
39
- status: 404,
40
- payload: '404 Not Found'
41
- }
42
- },
43
- {
44
- name: 'plain handler receives data, query and cookies',
45
- policy: false,
46
- request: {
47
- method: 'post',
48
- path: '/echo?q=z',
49
- headers: {
50
- 'content-type': 'application/json',
51
- cookie: 'id=666'
52
- },
53
- body: {
54
- a: 1
55
- }
56
- },
57
- expected: {
58
- kind: 'payload',
59
- status: 200,
60
- payload: {
61
- data: {
62
- a: 1
63
- },
64
- query: {
65
- q: 'z'
66
- },
67
- cookie: 'id=666'
68
- }
69
- }
70
- },
71
- {
72
- name: 'plain handler receives positional route params',
73
- policy: false,
74
- request: {
75
- method: 'get',
76
- path: '/items/123?q=x'
77
- },
78
- expected: {
79
- kind: 'payload',
80
- status: 200,
81
- payload: {
82
- id: '123',
83
- query: {
84
- q: 'x'
85
- }
86
- }
87
- }
88
- }
89
- ];
90
- export { createEnvelopeParityScenarios };
@@ -1,111 +0,0 @@
1
- import { PARITY_PRODUCER_REQUEST_ID, deniedScenario, detailHeader } from "./shared.mjs";
2
- const createOperationContextSuccessScenarios = ({ helloContract, validEnvelope, validOperationId })=>[
3
- {
4
- name: 'policy pass with full operation context',
5
- policy: true,
6
- request: {
7
- method: 'get',
8
- path: '/hello',
9
- headers: {
10
- 'x-modernjs-bff-envelope': validEnvelope,
11
- 'x-operation-id': validOperationId,
12
- 'x-modernjs-bff-operation-context': detailHeader({
13
- requestId: PARITY_PRODUCER_REQUEST_ID,
14
- method: 'GET',
15
- routePath: '/hello',
16
- schemaHash: helloContract.schemaHash,
17
- operationVersion: helloContract.operationVersion
18
- })
19
- }
20
- },
21
- expected: {
22
- kind: 'payload',
23
- status: 200,
24
- payload: {
25
- message: 'hello'
26
- }
27
- }
28
- }
29
- ];
30
- const getMismatchedOperationVersion = (contract)=>{
31
- const operationVersion = contract.operationVersion;
32
- if ('number' != typeof operationVersion) throw new Error('Adapter parity hello contract requires operationVersion');
33
- return operationVersion + 1;
34
- };
35
- const createOperationContextDenialScenarios = ({ helloContract, validEnvelope, validOperationId })=>[
36
- deniedScenario('policy denies missing operation context', 'missing_operation_context', {
37
- 'x-modernjs-bff-envelope': validEnvelope
38
- }),
39
- deniedScenario('policy denies operation context mismatch', 'operation_context_mismatch', {
40
- 'x-modernjs-bff-envelope': validEnvelope,
41
- 'x-operation-id': 'someone-else:parity'
42
- }),
43
- deniedScenario('policy denies missing operation context details', 'missing_operation_context_details', {
44
- 'x-modernjs-bff-envelope': validEnvelope,
45
- 'x-operation-id': validOperationId
46
- }),
47
- deniedScenario('policy denies JSON-array operation context details', 'invalid_operation_context_details', {
48
- 'x-modernjs-bff-envelope': validEnvelope,
49
- 'x-operation-id': validOperationId,
50
- 'x-modernjs-bff-operation-context': '[]'
51
- }),
52
- deniedScenario('policy denies invalid operation context details', 'invalid_operation_context_details', {
53
- 'x-modernjs-bff-envelope': validEnvelope,
54
- 'x-operation-id': validOperationId,
55
- 'x-modernjs-bff-operation-context': 'not-json'
56
- }),
57
- deniedScenario('policy denies detail requestId mismatch', 'operation_context_details_request_id_mismatch', {
58
- 'x-modernjs-bff-envelope': validEnvelope,
59
- 'x-operation-id': validOperationId,
60
- 'x-modernjs-bff-operation-context': detailHeader({
61
- requestId: 'crm.producer-b',
62
- method: 'GET',
63
- routePath: '/hello',
64
- schemaHash: helloContract.schemaHash,
65
- operationVersion: helloContract.operationVersion
66
- })
67
- }),
68
- deniedScenario('policy denies missing operation schema hash', 'missing_operation_schema_hash', {
69
- 'x-modernjs-bff-envelope': validEnvelope,
70
- 'x-operation-id': validOperationId,
71
- 'x-modernjs-bff-operation-context': detailHeader({
72
- requestId: PARITY_PRODUCER_REQUEST_ID,
73
- method: 'GET',
74
- routePath: '/hello',
75
- operationVersion: helloContract.operationVersion
76
- })
77
- }),
78
- deniedScenario('policy denies missing operation version', 'missing_operation_version', {
79
- 'x-modernjs-bff-envelope': validEnvelope,
80
- 'x-operation-id': validOperationId,
81
- 'x-modernjs-bff-operation-context': detailHeader({
82
- requestId: PARITY_PRODUCER_REQUEST_ID,
83
- method: 'GET',
84
- routePath: '/hello',
85
- schemaHash: helloContract.schemaHash
86
- })
87
- }),
88
- deniedScenario('policy denies operation schema hash mismatch', 'operation_schema_hash_mismatch', {
89
- 'x-modernjs-bff-envelope': validEnvelope,
90
- 'x-operation-id': validOperationId,
91
- 'x-modernjs-bff-operation-context': detailHeader({
92
- requestId: PARITY_PRODUCER_REQUEST_ID,
93
- method: 'GET',
94
- routePath: '/hello',
95
- schemaHash: 'deadbeef',
96
- operationVersion: helloContract.operationVersion
97
- })
98
- }),
99
- deniedScenario('policy denies operation version mismatch', 'operation_version_mismatch', {
100
- 'x-modernjs-bff-envelope': validEnvelope,
101
- 'x-operation-id': validOperationId,
102
- 'x-modernjs-bff-operation-context': detailHeader({
103
- requestId: PARITY_PRODUCER_REQUEST_ID,
104
- method: 'GET',
105
- routePath: '/hello',
106
- schemaHash: helloContract.schemaHash,
107
- operationVersion: getMismatchedOperationVersion(helloContract)
108
- })
109
- })
110
- ];
111
- export { createOperationContextDenialScenarios, createOperationContextSuccessScenarios };
@@ -1,71 +0,0 @@
1
- const createSchemaParityScenarios = ()=>[
2
- {
3
- name: 'schema handler success',
4
- policy: false,
5
- request: {
6
- method: 'patch',
7
- path: '/schema',
8
- headers: {
9
- 'content-type': 'application/json'
10
- },
11
- body: {
12
- id: 777
13
- }
14
- },
15
- expected: {
16
- kind: 'payload',
17
- status: 200,
18
- payload: {
19
- type: 'HandleSuccess',
20
- value: {
21
- id: 777
22
- }
23
- }
24
- }
25
- },
26
- {
27
- name: 'schema handler input validation error',
28
- policy: false,
29
- request: {
30
- method: 'patch',
31
- path: '/schema',
32
- headers: {
33
- 'content-type': 'application/json'
34
- },
35
- body: {
36
- id: 'aaa'
37
- }
38
- },
39
- expected: {
40
- kind: 'payload',
41
- status: 200,
42
- payload: {
43
- type: 'InputValidationError',
44
- message: 'invalid input'
45
- }
46
- }
47
- },
48
- {
49
- name: 'schema handler output validation error',
50
- policy: false,
51
- request: {
52
- method: 'patch',
53
- path: '/schema',
54
- headers: {
55
- 'content-type': 'application/json'
56
- },
57
- body: {
58
- id: 'boom'
59
- }
60
- },
61
- expected: {
62
- kind: 'payload',
63
- status: 200,
64
- payload: {
65
- type: 'OutputValidationError',
66
- message: 'invalid output'
67
- }
68
- }
69
- }
70
- ];
71
- export { createSchemaParityScenarios };
@@ -1,21 +0,0 @@
1
- const PARITY_REQUEST_ID = 'crm';
2
- const PARITY_PRODUCER_REQUEST_ID = 'crm.producer-a';
3
- const envelopeHeader = (requestId)=>JSON.stringify(void 0 === requestId ? {} : {
4
- requestId
5
- });
6
- const detailHeader = (details)=>JSON.stringify(details);
7
- const deniedScenario = (name, reason, headers)=>({
8
- name,
9
- policy: true,
10
- request: {
11
- method: 'get',
12
- path: '/hello',
13
- headers
14
- },
15
- expected: {
16
- kind: 'denied',
17
- status: 403,
18
- reason
19
- }
20
- });
21
- export { PARITY_PRODUCER_REQUEST_ID, PARITY_REQUEST_ID, deniedScenario, detailHeader, envelopeHeader };
@@ -1,148 +0,0 @@
1
- import { buildOperationContractMap } from "../security/operationContracts.mjs";
2
- import { HttpMethod } from "../types.mjs";
3
- import { createCrossProjectDenialScenarios } from "./parity-scenarios/cross-project-denial.mjs";
4
- import { createEnvelopeParityScenarios } from "./parity-scenarios/envelope.mjs";
5
- import { createOperationContextDenialScenarios, createOperationContextSuccessScenarios } from "./parity-scenarios/operation-context.mjs";
6
- import { createSchemaParityScenarios } from "./parity-scenarios/schema.mjs";
7
- import { PARITY_PRODUCER_REQUEST_ID, PARITY_REQUEST_ID, envelopeHeader } from "./parity-scenarios/shared.mjs";
8
- const PARITY_FIXTURE_FILENAME = 'bff-core/adapter-kit/parity-fixture.ts';
9
- const HANDLER_WITH_SCHEMA = 'HANDLER_WITH_SCHEMA';
10
- const isRecord = (value)=>Boolean(value) && 'object' == typeof value;
11
- const createSchemaFixtureHandler = ()=>{
12
- const handler = (input)=>{
13
- const data = isRecord(input) && isRecord(input.data) ? input.data : void 0;
14
- const id = data?.id;
15
- if ('number' == typeof id) return {
16
- type: 'HandleSuccess',
17
- value: {
18
- id
19
- }
20
- };
21
- if ('boom' === id) return {
22
- type: 'OutputValidationError',
23
- message: 'invalid output'
24
- };
25
- return {
26
- type: 'InputValidationError',
27
- message: 'invalid input'
28
- };
29
- };
30
- return Object.assign(handler, {
31
- [HANDLER_WITH_SCHEMA]: true
32
- });
33
- };
34
- const createParityApiHandlerInfos = ()=>[
35
- {
36
- name: 'getHello',
37
- httpMethod: HttpMethod.Get,
38
- routeName: '/hello',
39
- routePath: '/hello',
40
- filename: PARITY_FIXTURE_FILENAME,
41
- handler: ()=>({
42
- message: 'hello'
43
- })
44
- },
45
- {
46
- name: 'postHello',
47
- httpMethod: HttpMethod.Post,
48
- routeName: '/hello',
49
- routePath: '/hello',
50
- filename: PARITY_FIXTURE_FILENAME,
51
- handler: ()=>'hello'
52
- },
53
- {
54
- name: 'getNothing',
55
- httpMethod: HttpMethod.Get,
56
- routeName: '/nothing',
57
- routePath: '/nothing',
58
- filename: PARITY_FIXTURE_FILENAME,
59
- handler: ()=>void 0
60
- },
61
- {
62
- name: 'postEcho',
63
- httpMethod: HttpMethod.Post,
64
- routeName: '/echo',
65
- routePath: '/echo',
66
- filename: PARITY_FIXTURE_FILENAME,
67
- handler: (input)=>{
68
- const normalized = isRecord(input) ? input : {};
69
- return {
70
- data: normalized.data ?? null,
71
- query: normalized.query ?? {},
72
- cookie: normalized.cookies ?? null
73
- };
74
- }
75
- },
76
- {
77
- name: 'getItem',
78
- httpMethod: HttpMethod.Get,
79
- routeName: '/items/:id',
80
- routePath: '/items/:id',
81
- filename: PARITY_FIXTURE_FILENAME,
82
- handler: (id, input)=>({
83
- id,
84
- query: isRecord(input) ? input.query ?? {} : {}
85
- })
86
- },
87
- {
88
- name: 'patchSchema',
89
- httpMethod: HttpMethod.Patch,
90
- routeName: '/schema',
91
- routePath: '/schema',
92
- filename: PARITY_FIXTURE_FILENAME,
93
- handler: createSchemaFixtureHandler()
94
- }
95
- ];
96
- const createParityBffConfig = ()=>({
97
- requestId: PARITY_PRODUCER_REQUEST_ID,
98
- crossProjectPolicy: {
99
- enabled: true,
100
- allowedNamespaces: [
101
- PARITY_REQUEST_ID
102
- ],
103
- allowClientAssertedNamespace: true
104
- }
105
- });
106
- const getParityContracts = ()=>buildOperationContractMap({
107
- handlers: createParityApiHandlerInfos(),
108
- requestId: PARITY_PRODUCER_REQUEST_ID
109
- });
110
- const createAdapterParityScenarios = ()=>{
111
- const contracts = getParityContracts();
112
- const helloContract = contracts['GET:/hello'];
113
- const validEnvelope = envelopeHeader(PARITY_PRODUCER_REQUEST_ID);
114
- const validOperationId = helloContract.operationId;
115
- const context = {
116
- helloContract,
117
- validEnvelope,
118
- validOperationId
119
- };
120
- return [
121
- ...createEnvelopeParityScenarios(),
122
- ...createSchemaParityScenarios(),
123
- ...createOperationContextSuccessScenarios(context),
124
- ...createCrossProjectDenialScenarios(),
125
- ...createOperationContextDenialScenarios(context)
126
- ];
127
- };
128
- const toParityResult = (res)=>({
129
- status: res.status,
130
- payload: res.type.includes('json') ? res.body : '' === res.text ? void 0 : res.text
131
- });
132
- const formatValue = (value)=>JSON.stringify(value);
133
- const assertParityResult = (scenario, res)=>{
134
- const result = toParityResult(res);
135
- const failures = [];
136
- const { expected } = scenario;
137
- if (result.status !== expected.status) failures.push(`status: expected ${expected.status}, received ${result.status}`);
138
- if ('payload' === expected.kind) {
139
- if (formatValue(result.payload) !== formatValue(expected.payload)) failures.push(`payload: expected ${formatValue(expected.payload)}, received ${formatValue(result.payload)}`);
140
- } else {
141
- const payload = isRecord(result.payload) ? result.payload : {};
142
- if ('BFF_CROSS_PROJECT_POLICY_DENIED' !== payload.code) failures.push(`denial code: expected "BFF_CROSS_PROJECT_POLICY_DENIED", received ${formatValue(payload.code)}`);
143
- if (payload.reason !== expected.reason) failures.push(`denial reason: expected "${expected.reason}", received ${formatValue(payload.reason)}`);
144
- if ('string' != typeof payload.message || 0 === payload.message.length) failures.push(`denial message: expected non-empty string, received ${formatValue(payload.message)}`);
145
- }
146
- if (failures.length > 0) throw new Error(`Adapter parity scenario "${scenario.name}" failed:\n- ${failures.join('\n- ')}`);
147
- };
148
- export { PARITY_PRODUCER_REQUEST_ID, PARITY_REQUEST_ID, assertParityResult, createAdapterParityScenarios, createParityApiHandlerInfos, createParityBffConfig, toParityResult };