@entifix/rest 0.1.0-0
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/LICENSE +21 -0
- package/README.md +11 -0
- package/dist/adapters/entity-metadata/make-entity-metadata-source/index.d.ts +2 -0
- package/dist/adapters/entity-metadata/make-entity-metadata-source/index.d.ts.map +1 -0
- package/dist/adapters/entity-metadata/make-entity-metadata-source/index.js +3 -0
- package/dist/adapters/entity-metadata/make-entity-metadata-source/index.js.map +1 -0
- package/dist/adapters/entity-metadata/make-entity-metadata-source/make-entity-metadata-source.d.ts +23 -0
- package/dist/adapters/entity-metadata/make-entity-metadata-source/make-entity-metadata-source.d.ts.map +1 -0
- package/dist/adapters/entity-metadata/make-entity-metadata-source/make-entity-metadata-source.js +45 -0
- package/dist/adapters/entity-metadata/make-entity-metadata-source/make-entity-metadata-source.js.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/build-entity-rest-adapter-delete.d.ts +13 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/build-entity-rest-adapter-delete.d.ts.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/build-entity-rest-adapter-delete.js +34 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/build-entity-rest-adapter-delete.js.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/index.d.ts +2 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/index.d.ts.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/index.js +3 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/index.js.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-get/build-entity-rest-adapter-get.d.ts +6 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-get/build-entity-rest-adapter-get.d.ts.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-get/build-entity-rest-adapter-get.js +21 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-get/build-entity-rest-adapter-get.js.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-get/index.d.ts +2 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-get/index.d.ts.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-get/index.js +3 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-get/index.js.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-load/build-entity-rest-adapter-load.d.ts +6 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-load/build-entity-rest-adapter-load.d.ts.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-load/build-entity-rest-adapter-load.js +31 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-load/build-entity-rest-adapter-load.js.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-load/index.d.ts +2 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-load/index.d.ts.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-load/index.js +3 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-load/index.js.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-base-url.d.ts +5 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-base-url.d.ts.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-base-url.js +10 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-base-url.js.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-request.d.ts +19 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-request.d.ts.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-request.js +17 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-request.js.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/index.d.ts +5 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/index.d.ts.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/index.js +8 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/index.js.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-save/build-entity-rest-adapter-save.d.ts +25 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-save/build-entity-rest-adapter-save.d.ts.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-save/build-entity-rest-adapter-save.js +92 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-save/build-entity-rest-adapter-save.js.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-save/index.d.ts +2 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-save/index.d.ts.map +1 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-save/index.js +3 -0
- package/dist/adapters/entity-rest/build-entity-rest-adapter-save/index.js.map +1 -0
- package/dist/adapters/entity-rest/types.d.ts +24 -0
- package/dist/adapters/entity-rest/types.d.ts.map +1 -0
- package/dist/adapters/entity-rest/types.js +3 -0
- package/dist/adapters/entity-rest/types.js.map +1 -0
- package/dist/adapters/transaction-status/build-transaction-status-reader/build-transaction-status-reader.d.ts +23 -0
- package/dist/adapters/transaction-status/build-transaction-status-reader/build-transaction-status-reader.d.ts.map +1 -0
- package/dist/adapters/transaction-status/build-transaction-status-reader/build-transaction-status-reader.js +45 -0
- package/dist/adapters/transaction-status/build-transaction-status-reader/build-transaction-status-reader.js.map +1 -0
- package/dist/adapters/transaction-status/build-transaction-status-reader/index.d.ts +2 -0
- package/dist/adapters/transaction-status/build-transaction-status-reader/index.d.ts.map +1 -0
- package/dist/adapters/transaction-status/build-transaction-status-reader/index.js +3 -0
- package/dist/adapters/transaction-status/build-transaction-status-reader/index.js.map +1 -0
- package/dist/clients/fetch/fetch-client.d.ts +5 -0
- package/dist/clients/fetch/fetch-client.d.ts.map +1 -0
- package/dist/clients/fetch/fetch-client.js +53 -0
- package/dist/clients/fetch/fetch-client.js.map +1 -0
- package/dist/clients/fetch/index.d.ts +2 -0
- package/dist/clients/fetch/index.d.ts.map +1 -0
- package/dist/clients/fetch/index.js +3 -0
- package/dist/clients/fetch/index.js.map +1 -0
- package/dist/clients/types.d.ts +14 -0
- package/dist/clients/types.d.ts.map +1 -0
- package/dist/clients/types.js +3 -0
- package/dist/clients/types.js.map +1 -0
- package/dist/configuration-client/configuration-client-rest-client.d.ts +28 -0
- package/dist/configuration-client/configuration-client-rest-client.d.ts.map +1 -0
- package/dist/configuration-client/configuration-client-rest-client.js +94 -0
- package/dist/configuration-client/configuration-client-rest-client.js.map +1 -0
- package/dist/configuration-client/index.d.ts +2 -0
- package/dist/configuration-client/index.d.ts.map +1 -0
- package/dist/configuration-client/index.js +3 -0
- package/dist/configuration-client/index.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/package.json +68 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 r10c Technologies
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# @entifix/rest
|
|
2
|
+
|
|
3
|
+
This library was generated with [Nx](https://nx.dev).
|
|
4
|
+
|
|
5
|
+
## Building
|
|
6
|
+
|
|
7
|
+
Run `nx build @entifix/rest` to build the library.
|
|
8
|
+
|
|
9
|
+
## Running unit tests
|
|
10
|
+
|
|
11
|
+
Run `nx test @entifix/rest` to execute the unit tests via [Jest](https://jestjs.io).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapters/entity-metadata/make-entity-metadata-source/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/entity-metadata/make-entity-metadata-source/index.ts"],"sourcesContent":["export * from './make-entity-metadata-source.js';\n"],"names":[],"mappings":"AAAA,cAAc,mCAAmC"}
|
package/dist/adapters/entity-metadata/make-entity-metadata-source/make-entity-metadata-source.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type EntityMetadataSource } from '@entifix/core';
|
|
2
|
+
export interface EntityMetadataSourceOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Where this entity's document lives, given its envelope name.
|
|
5
|
+
*
|
|
6
|
+
* A builder rather than the adapters' `BuildEntityRestOptions`, because the
|
|
7
|
+
* two consumers resolve their base differently: the catalog goes through
|
|
8
|
+
* `buildEntityBaseUrl`'s config-driven `compose` mode, while a Next shell with
|
|
9
|
+
* hand-written same-origin routes has no adapters context at all. Both can
|
|
10
|
+
* write one arrow function.
|
|
11
|
+
*/
|
|
12
|
+
url: (entityName: string) => string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Fetches an entity's {@link EntityMetadataDocument} over HTTP.
|
|
16
|
+
*
|
|
17
|
+
* The response is permission-filtered by the service against the *verified*
|
|
18
|
+
* principal, so nothing here re-checks anything: this reads what the caller was
|
|
19
|
+
* told they may do. Cookies ride along by `fetch`'s same-origin default, which
|
|
20
|
+
* is what carries the session on a Next shell's own `/api` route.
|
|
21
|
+
*/
|
|
22
|
+
export declare const makeEntityMetadataSource: ({ url, }: EntityMetadataSourceOptions) => EntityMetadataSource;
|
|
23
|
+
//# sourceMappingURL=make-entity-metadata-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"make-entity-metadata-source.d.ts","sourceRoot":"","sources":["../../../../src/adapters/entity-metadata/make-entity-metadata-source/make-entity-metadata-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,oBAAoB,EAG1B,MAAM,eAAe,CAAC;AAGvB,MAAM,WAAW,2BAA2B;IAC1C;;;;;;;;OAQG;IACH,GAAG,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,GAAI,UAEtC,2BAA2B,KAAG,oBAgD/B,CAAC"}
|
package/dist/adapters/entity-metadata/make-entity-metadata-source/make-entity-metadata-source.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { EntifixConnError, envelopeEntityName, readEntityMetadataEnvelope } from '@entifix/core';
|
|
2
|
+
import { Effect } from 'effect';
|
|
3
|
+
/**
|
|
4
|
+
* Fetches an entity's {@link EntityMetadataDocument} over HTTP.
|
|
5
|
+
*
|
|
6
|
+
* The response is permission-filtered by the service against the *verified*
|
|
7
|
+
* principal, so nothing here re-checks anything: this reads what the caller was
|
|
8
|
+
* told they may do. Cookies ride along by `fetch`'s same-origin default, which
|
|
9
|
+
* is what carries the session on a Next shell's own `/api` route.
|
|
10
|
+
*/ export const makeEntityMetadataSource = ({ url })=>({
|
|
11
|
+
fetchMetadata: (entityConstructor)=>{
|
|
12
|
+
const name = envelopeEntityName(entityConstructor);
|
|
13
|
+
return Effect.runPromise(Effect.gen(function*() {
|
|
14
|
+
const response = yield* Effect.tryPromise({
|
|
15
|
+
try: ()=>fetch(url(name), {
|
|
16
|
+
headers: {
|
|
17
|
+
Accept: 'application/json'
|
|
18
|
+
}
|
|
19
|
+
}),
|
|
20
|
+
catch: (error)=>new EntifixConnError(`Metadata request for "${name}" failed`, error, {
|
|
21
|
+
entity: name
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
// A `404` here is deliberate on the service side and means "not
|
|
26
|
+
// readable, or not hosted" — the endpoint refuses to distinguish the
|
|
27
|
+
// two so it cannot be walked to enumerate the model. Either way the
|
|
28
|
+
// caller has no affordances, so it is an error, not an empty document.
|
|
29
|
+
return yield* Effect.fail(new EntifixConnError(`Metadata request for "${name}" failed with status ${response.status}`, undefined, {
|
|
30
|
+
entity: name,
|
|
31
|
+
status: response.status
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
const body = yield* Effect.tryPromise({
|
|
35
|
+
try: ()=>response.json(),
|
|
36
|
+
catch: (error)=>new EntifixConnError(`Metadata response for "${name}" was not JSON`, error, {
|
|
37
|
+
entity: name
|
|
38
|
+
})
|
|
39
|
+
});
|
|
40
|
+
return yield* readEntityMetadataEnvelope(entityConstructor, body);
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=make-entity-metadata-source.js.map
|
package/dist/adapters/entity-metadata/make-entity-metadata-source/make-entity-metadata-source.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/entity-metadata/make-entity-metadata-source/make-entity-metadata-source.ts"],"sourcesContent":["import {\n EntifixConnError,\n type Entity,\n type EntityConstructor,\n type EntityMetadataDocument,\n type EntityMetadataSource,\n envelopeEntityName,\n readEntityMetadataEnvelope,\n} from '@entifix/core';\nimport { Effect } from 'effect';\n\nexport interface EntityMetadataSourceOptions {\n /**\n * Where this entity's document lives, given its envelope name.\n *\n * A builder rather than the adapters' `BuildEntityRestOptions`, because the\n * two consumers resolve their base differently: the catalog goes through\n * `buildEntityBaseUrl`'s config-driven `compose` mode, while a Next shell with\n * hand-written same-origin routes has no adapters context at all. Both can\n * write one arrow function.\n */\n url: (entityName: string) => string;\n}\n\n/**\n * Fetches an entity's {@link EntityMetadataDocument} over HTTP.\n *\n * The response is permission-filtered by the service against the *verified*\n * principal, so nothing here re-checks anything: this reads what the caller was\n * told they may do. Cookies ride along by `fetch`'s same-origin default, which\n * is what carries the session on a Next shell's own `/api` route.\n */\nexport const makeEntityMetadataSource = ({\n url,\n}: EntityMetadataSourceOptions): EntityMetadataSource => ({\n fetchMetadata: <TEntity extends Entity>(\n entityConstructor: EntityConstructor<TEntity>,\n ): Promise<EntityMetadataDocument> => {\n const name = envelopeEntityName(entityConstructor);\n return Effect.runPromise(\n Effect.gen(function* () {\n const response = yield* Effect.tryPromise({\n try: () =>\n fetch(url(name), { headers: { Accept: 'application/json' } }),\n catch: error =>\n new EntifixConnError(\n `Metadata request for \"${name}\" failed`,\n error,\n {\n entity: name,\n },\n ),\n });\n\n if (!response.ok) {\n // A `404` here is deliberate on the service side and means \"not\n // readable, or not hosted\" — the endpoint refuses to distinguish the\n // two so it cannot be walked to enumerate the model. Either way the\n // caller has no affordances, so it is an error, not an empty document.\n return yield* Effect.fail(\n new EntifixConnError(\n `Metadata request for \"${name}\" failed with status ${response.status}`,\n undefined,\n { entity: name, status: response.status },\n ),\n );\n }\n\n const body = yield* Effect.tryPromise({\n try: () => response.json() as Promise<unknown>,\n catch: error =>\n new EntifixConnError(\n `Metadata response for \"${name}\" was not JSON`,\n error,\n { entity: name },\n ),\n });\n\n return yield* readEntityMetadataEnvelope(entityConstructor, body);\n }),\n );\n },\n});\n"],"names":["EntifixConnError","envelopeEntityName","readEntityMetadataEnvelope","Effect","makeEntityMetadataSource","url","fetchMetadata","entityConstructor","name","runPromise","gen","response","tryPromise","try","fetch","headers","Accept","catch","error","entity","ok","fail","status","undefined","body","json"],"mappings":"AAAA,SACEA,gBAAgB,EAKhBC,kBAAkB,EAClBC,0BAA0B,QACrB,gBAAgB;AACvB,SAASC,MAAM,QAAQ,SAAS;AAehC;;;;;;;CAOC,GACD,OAAO,MAAMC,2BAA2B,CAAC,EACvCC,GAAG,EACyB,GAA4B,CAAA;QACxDC,eAAe,CACbC;YAEA,MAAMC,OAAOP,mBAAmBM;YAChC,OAAOJ,OAAOM,UAAU,CACtBN,OAAOO,GAAG,CAAC;gBACT,MAAMC,WAAW,OAAOR,OAAOS,UAAU,CAAC;oBACxCC,KAAK,IACHC,MAAMT,IAAIG,OAAO;4BAAEO,SAAS;gCAAEC,QAAQ;4BAAmB;wBAAE;oBAC7DC,OAAOC,CAAAA,QACL,IAAIlB,iBACF,CAAC,sBAAsB,EAAEQ,KAAK,QAAQ,CAAC,EACvCU,OACA;4BACEC,QAAQX;wBACV;gBAEN;gBAEA,IAAI,CAACG,SAASS,EAAE,EAAE;oBAChB,gEAAgE;oBAChE,qEAAqE;oBACrE,oEAAoE;oBACpE,uEAAuE;oBACvE,OAAO,OAAOjB,OAAOkB,IAAI,CACvB,IAAIrB,iBACF,CAAC,sBAAsB,EAAEQ,KAAK,qBAAqB,EAAEG,SAASW,MAAM,EAAE,EACtEC,WACA;wBAAEJ,QAAQX;wBAAMc,QAAQX,SAASW,MAAM;oBAAC;gBAG9C;gBAEA,MAAME,OAAO,OAAOrB,OAAOS,UAAU,CAAC;oBACpCC,KAAK,IAAMF,SAASc,IAAI;oBACxBR,OAAOC,CAAAA,QACL,IAAIlB,iBACF,CAAC,uBAAuB,EAAEQ,KAAK,cAAc,CAAC,EAC9CU,OACA;4BAAEC,QAAQX;wBAAK;gBAErB;gBAEA,OAAO,OAAON,2BAA2BK,mBAAmBiB;YAC9D;QAEJ;IACF,CAAA,EAAG"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ConfigurationRepositoryTag } from '@entifix/business';
|
|
2
|
+
import { Entity, EntityConstructor, EntityId } from '@entifix/core';
|
|
3
|
+
import { Effect } from 'effect';
|
|
4
|
+
import { BuildEntityRestOptions } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Deletes an entity over HTTP.
|
|
7
|
+
*
|
|
8
|
+
* The response body is discarded, but the service still answers with an
|
|
9
|
+
* envelope rather than a bare `204`: the shared fetch client always parses the
|
|
10
|
+
* response as JSON, and an empty body would fail that parse.
|
|
11
|
+
*/
|
|
12
|
+
export declare const buildEntityRestAdapterDelete: <TEntity extends Entity>(entityConstructor: EntityConstructor<TEntity>, { uriConfig }: BuildEntityRestOptions) => <TEntity_1 extends Entity>(entityOrId: EntityId | TEntity_1) => Effect.Effect<undefined, import("@entifix/core").EntifixBuildError | import("@entifix/core").EntifixConnError, ConfigurationRepositoryTag>;
|
|
13
|
+
//# sourceMappingURL=build-entity-rest-adapter-delete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-entity-rest-adapter-delete.d.ts","sourceRoot":"","sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-delete/build-entity-rest-adapter-delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAEL,MAAM,EACN,iBAAiB,EACjB,QAAQ,EAET,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AASrD;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GACtC,OAAO,SAAS,MAAM,EACrB,mBAAmB,iBAAiB,CAAC,OAAO,CAAC,EAC7C,eAAe,sBAAsB,MAEtC,SAAO,SAAS,MAAM,EAAE,YAAY,QAAQ,GAAG,SAAO,+IA0BnD,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ConfigurationRepositoryTag } from '@entifix/business';
|
|
2
|
+
import { EntifixLogicError, extractMetaEntity } from '@entifix/core';
|
|
3
|
+
import { Effect } from 'effect';
|
|
4
|
+
import { performHttpRequestThroughFetch } from '../../../clients/fetch/index.js';
|
|
5
|
+
import { buildEntityRestAdapterMixins as adapterMixins } from '../build-entity-rest-adapter-mixins/index.js';
|
|
6
|
+
/** Accepts either an id or a whole entity, mirroring the repository contract. */ function toEntityId(entityOrId) {
|
|
7
|
+
return entityOrId != null && typeof entityOrId === 'object' ? entityOrId.id : entityOrId;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Deletes an entity over HTTP.
|
|
11
|
+
*
|
|
12
|
+
* The response body is discarded, but the service still answers with an
|
|
13
|
+
* envelope rather than a bare `204`: the shared fetch client always parses the
|
|
14
|
+
* response as JSON, and an empty body would fail that parse.
|
|
15
|
+
*/ export const buildEntityRestAdapterDelete = (entityConstructor, { uriConfig })=>(entityOrId)=>Effect.gen(function*() {
|
|
16
|
+
var _metaEntity_key;
|
|
17
|
+
const configurationStore = yield* ConfigurationRepositoryTag;
|
|
18
|
+
const metaEntity = extractMetaEntity(entityConstructor);
|
|
19
|
+
const id = toEntityId(entityOrId);
|
|
20
|
+
if (id == null) {
|
|
21
|
+
return yield* Effect.fail(new EntifixLogicError(`Cannot delete a ${entityConstructor.name} without an id`, undefined, {
|
|
22
|
+
entity: entityConstructor.name
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
const url = yield* adapterMixins.buildEntityBaseUrl(configurationStore, {
|
|
26
|
+
uriConfig
|
|
27
|
+
}, (_metaEntity_key = metaEntity.key) != null ? _metaEntity_key : metaEntity.name, String(id));
|
|
28
|
+
yield* performHttpRequestThroughFetch(adapterMixins.buildEntityRequest({
|
|
29
|
+
method: 'DELETE',
|
|
30
|
+
url
|
|
31
|
+
}));
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=build-entity-rest-adapter-delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-delete/build-entity-rest-adapter-delete.ts"],"sourcesContent":["import { ConfigurationRepositoryTag } from '@entifix/business';\nimport {\n EntifixLogicError,\n Entity,\n EntityConstructor,\n EntityId,\n extractMetaEntity,\n} from '@entifix/core';\nimport { Effect } from 'effect';\n\nimport { performHttpRequestThroughFetch } from '../../../clients/fetch/index.js';\nimport { buildEntityRestAdapterMixins as adapterMixins } from '../build-entity-rest-adapter-mixins/index.js';\nimport { BuildEntityRestOptions } from '../types.js';\n\n/** Accepts either an id or a whole entity, mirroring the repository contract. */\nfunction toEntityId(entityOrId: EntityId | Entity): EntityId {\n return entityOrId != null && typeof entityOrId === 'object'\n ? (entityOrId as Entity).id\n : (entityOrId as EntityId);\n}\n\n/**\n * Deletes an entity over HTTP.\n *\n * The response body is discarded, but the service still answers with an\n * envelope rather than a bare `204`: the shared fetch client always parses the\n * response as JSON, and an empty body would fail that parse.\n */\nexport const buildEntityRestAdapterDelete =\n <TEntity extends Entity>(\n entityConstructor: EntityConstructor<TEntity>,\n { uriConfig }: BuildEntityRestOptions,\n ) =>\n <TEntity extends Entity>(entityOrId: EntityId | TEntity) =>\n Effect.gen(function* () {\n const configurationStore = yield* ConfigurationRepositoryTag;\n const metaEntity = extractMetaEntity(entityConstructor);\n const id = toEntityId(entityOrId);\n\n if (id == null) {\n return yield* Effect.fail(\n new EntifixLogicError(\n `Cannot delete a ${entityConstructor.name} without an id`,\n undefined,\n { entity: entityConstructor.name },\n ),\n );\n }\n\n const url = yield* adapterMixins.buildEntityBaseUrl(\n configurationStore,\n { uriConfig },\n metaEntity.key ?? metaEntity.name,\n String(id),\n );\n\n yield* performHttpRequestThroughFetch(\n adapterMixins.buildEntityRequest({ method: 'DELETE', url }),\n );\n });\n"],"names":["ConfigurationRepositoryTag","EntifixLogicError","extractMetaEntity","Effect","performHttpRequestThroughFetch","buildEntityRestAdapterMixins","adapterMixins","toEntityId","entityOrId","id","buildEntityRestAdapterDelete","entityConstructor","uriConfig","gen","metaEntity","configurationStore","fail","name","undefined","entity","url","buildEntityBaseUrl","key","String","buildEntityRequest","method"],"mappings":"AAAA,SAASA,0BAA0B,QAAQ,oBAAoB;AAC/D,SACEC,iBAAiB,EAIjBC,iBAAiB,QACZ,gBAAgB;AACvB,SAASC,MAAM,QAAQ,SAAS;AAEhC,SAASC,8BAA8B,QAAQ,kCAAkC;AACjF,SAASC,gCAAgCC,aAAa,QAAQ,+CAA+C;AAG7G,+EAA+E,GAC/E,SAASC,WAAWC,UAA6B;IAC/C,OAAOA,cAAc,QAAQ,OAAOA,eAAe,WAC/C,AAACA,WAAsBC,EAAE,GACxBD;AACP;AAEA;;;;;;CAMC,GACD,OAAO,MAAME,+BACX,CACEC,mBACA,EAAEC,SAAS,EAA0B,GAEvC,CAAyBJ,aACvBL,OAAOU,GAAG,CAAC;gBAkBPC;YAjBF,MAAMC,qBAAqB,OAAOf;YAClC,MAAMc,aAAaZ,kBAAkBS;YACrC,MAAMF,KAAKF,WAAWC;YAEtB,IAAIC,MAAM,MAAM;gBACd,OAAO,OAAON,OAAOa,IAAI,CACvB,IAAIf,kBACF,CAAC,gBAAgB,EAAEU,kBAAkBM,IAAI,CAAC,cAAc,CAAC,EACzDC,WACA;oBAAEC,QAAQR,kBAAkBM,IAAI;gBAAC;YAGvC;YAEA,MAAMG,MAAM,OAAOd,cAAce,kBAAkB,CACjDN,oBACA;gBAAEH;YAAU,IACZE,kBAAAA,WAAWQ,GAAG,YAAdR,kBAAkBA,WAAWG,IAAI,EACjCM,OAAOd;YAGT,OAAOL,+BACLE,cAAckB,kBAAkB,CAAC;gBAAEC,QAAQ;gBAAUL;YAAI;QAE7D,GAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-delete/index.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-delete/index.ts"],"sourcesContent":["export * from './build-entity-rest-adapter-delete.js';\n"],"names":[],"mappings":"AAAA,cAAc,wCAAwC"}
|
package/dist/adapters/entity-rest/build-entity-rest-adapter-get/build-entity-rest-adapter-get.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ConfigurationRepositoryTag } from '@entifix/business';
|
|
2
|
+
import { Entity, EntityConstructor } from '@entifix/core';
|
|
3
|
+
import { Effect } from 'effect';
|
|
4
|
+
import { BuildEntityRestOptions } from '../types.js';
|
|
5
|
+
export declare const buildEntityRestAdapterGet: <TEntity extends Entity>(entityConstructor: EntityConstructor<TEntity>, { uriConfig }: BuildEntityRestOptions) => <TEntity_1 extends Entity>(entityId: string) => Effect.Effect<TEntity_1, import("@entifix/core").EntifixBuildError | import("@entifix/core").EntifixConnError, ConfigurationRepositoryTag>;
|
|
6
|
+
//# sourceMappingURL=build-entity-rest-adapter-get.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-entity-rest-adapter-get.d.ts","sourceRoot":"","sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-get/build-entity-rest-adapter-get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EACL,MAAM,EACN,iBAAiB,EAGlB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAErD,eAAO,MAAM,yBAAyB,GACnC,OAAO,SAAS,MAAM,EACrB,mBAAmB,iBAAiB,CAAC,OAAO,CAAC,EAC7C,eAAe,sBAAsB,MAEtC,SAAO,SAAS,MAAM,EAAE,UAAU,MAAM,+IAqBrC,CAAC"}
|
package/dist/adapters/entity-rest/build-entity-rest-adapter-get/build-entity-rest-adapter-get.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ConfigurationRepositoryTag } from '@entifix/business';
|
|
2
|
+
import { extractMetaEntity, readEntityEnvelope } from '@entifix/core';
|
|
3
|
+
import { Effect } from 'effect';
|
|
4
|
+
import { performHttpRequestThroughFetch } from '../../../clients/fetch/index.js';
|
|
5
|
+
import { buildEntityRestAdapterMixins as adapterMixins } from '../build-entity-rest-adapter-mixins/index.js';
|
|
6
|
+
export const buildEntityRestAdapterGet = (entityConstructor, { uriConfig })=>(entityId)=>Effect.gen(function*() {
|
|
7
|
+
var _metaEntity_key;
|
|
8
|
+
const configurationStore = yield* ConfigurationRepositoryTag;
|
|
9
|
+
const metaEntity = extractMetaEntity(entityConstructor);
|
|
10
|
+
const entityUrl = yield* adapterMixins.buildEntityBaseUrl(configurationStore, {
|
|
11
|
+
uriConfig
|
|
12
|
+
}, (_metaEntity_key = metaEntity.key) != null ? _metaEntity_key : metaEntity.name, entityId);
|
|
13
|
+
const response = yield* performHttpRequestThroughFetch(adapterMixins.buildEntityRequest({
|
|
14
|
+
method: 'GET',
|
|
15
|
+
url: entityUrl
|
|
16
|
+
}));
|
|
17
|
+
const entity = yield* readEntityEnvelope(entityConstructor, response.body);
|
|
18
|
+
return entity;
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=build-entity-rest-adapter-get.js.map
|
package/dist/adapters/entity-rest/build-entity-rest-adapter-get/build-entity-rest-adapter-get.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-get/build-entity-rest-adapter-get.ts"],"sourcesContent":["import { ConfigurationRepositoryTag } from '@entifix/business';\nimport {\n Entity,\n EntityConstructor,\n extractMetaEntity,\n readEntityEnvelope,\n} from '@entifix/core';\nimport { Effect } from 'effect';\n\nimport { performHttpRequestThroughFetch } from '../../../clients/fetch/index.js';\nimport { buildEntityRestAdapterMixins as adapterMixins } from '../build-entity-rest-adapter-mixins/index.js';\nimport { BuildEntityRestOptions } from '../types.js';\n\nexport const buildEntityRestAdapterGet =\n <TEntity extends Entity>(\n entityConstructor: EntityConstructor<TEntity>,\n { uriConfig }: BuildEntityRestOptions,\n ) =>\n <TEntity extends Entity>(entityId: string) =>\n Effect.gen(function* () {\n const configurationStore = yield* ConfigurationRepositoryTag;\n const metaEntity = extractMetaEntity(entityConstructor);\n\n const entityUrl = yield* adapterMixins.buildEntityBaseUrl(\n configurationStore,\n { uriConfig },\n metaEntity.key ?? metaEntity.name,\n entityId,\n );\n\n const response = yield* performHttpRequestThroughFetch(\n adapterMixins.buildEntityRequest({ method: 'GET', url: entityUrl }),\n );\n const entity = yield* readEntityEnvelope(\n entityConstructor,\n response.body,\n );\n\n return entity as unknown as TEntity;\n });\n"],"names":["ConfigurationRepositoryTag","extractMetaEntity","readEntityEnvelope","Effect","performHttpRequestThroughFetch","buildEntityRestAdapterMixins","adapterMixins","buildEntityRestAdapterGet","entityConstructor","uriConfig","entityId","gen","metaEntity","configurationStore","entityUrl","buildEntityBaseUrl","key","name","response","buildEntityRequest","method","url","entity","body"],"mappings":"AAAA,SAASA,0BAA0B,QAAQ,oBAAoB;AAC/D,SAGEC,iBAAiB,EACjBC,kBAAkB,QACb,gBAAgB;AACvB,SAASC,MAAM,QAAQ,SAAS;AAEhC,SAASC,8BAA8B,QAAQ,kCAAkC;AACjF,SAASC,gCAAgCC,aAAa,QAAQ,+CAA+C;AAG7G,OAAO,MAAMC,4BACX,CACEC,mBACA,EAAEC,SAAS,EAA0B,GAEvC,CAAyBC,WACvBP,OAAOQ,GAAG,CAAC;gBAOPC;YANF,MAAMC,qBAAqB,OAAOb;YAClC,MAAMY,aAAaX,kBAAkBO;YAErC,MAAMM,YAAY,OAAOR,cAAcS,kBAAkB,CACvDF,oBACA;gBAAEJ;YAAU,IACZG,kBAAAA,WAAWI,GAAG,YAAdJ,kBAAkBA,WAAWK,IAAI,EACjCP;YAGF,MAAMQ,WAAW,OAAOd,+BACtBE,cAAca,kBAAkB,CAAC;gBAAEC,QAAQ;gBAAOC,KAAKP;YAAU;YAEnE,MAAMQ,SAAS,OAAOpB,mBACpBM,mBACAU,SAASK,IAAI;YAGf,OAAOD;QACT,GAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-get/index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-get/index.ts"],"sourcesContent":["export * from './build-entity-rest-adapter-get.js';\n"],"names":[],"mappings":"AAAA,cAAc,qCAAqC"}
|
package/dist/adapters/entity-rest/build-entity-rest-adapter-load/build-entity-rest-adapter-load.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ConfigurationRepositoryTag } from '@entifix/business';
|
|
2
|
+
import { Entity, EntityConstructor, EntityLoadRequest, EntityPage } from '@entifix/core';
|
|
3
|
+
import { Effect } from 'effect';
|
|
4
|
+
import { BuildEntityRestOptions } from '../types.js';
|
|
5
|
+
export declare const buildEntityRestAdapterLoad: <TEntity extends Entity>(entityConstructor: EntityConstructor<TEntity>, { uriConfig }: BuildEntityRestOptions) => <TEntity_1 extends Entity>(request: EntityLoadRequest<TEntity_1>) => Effect.Effect<EntityPage<TEntity_1>, import("@entifix/core").EntifixBuildError | import("@entifix/core").EntifixConnError, ConfigurationRepositoryTag>;
|
|
6
|
+
//# sourceMappingURL=build-entity-rest-adapter-load.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-entity-rest-adapter-load.d.ts","sourceRoot":"","sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-load/build-entity-rest-adapter-load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EACL,MAAM,EACN,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EAIX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAErD,eAAO,MAAM,0BAA0B,GACpC,OAAO,SAAS,MAAM,EACrB,mBAAmB,iBAAiB,CAAC,OAAO,CAAC,EAC7C,eAAe,sBAAsB,MAEtC,SAAO,SAAS,MAAM,EAAE,SAAS,iBAAiB,CAAC,SAAO,CAAC,2JA+BxD,CAAC"}
|
package/dist/adapters/entity-rest/build-entity-rest-adapter-load/build-entity-rest-adapter-load.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
import { ConfigurationRepositoryTag } from '@entifix/business';
|
|
3
|
+
import { extractMetaEntity, readEntityPageEnvelope, serializeLoadRequestParams } from '@entifix/core';
|
|
4
|
+
import { Effect } from 'effect';
|
|
5
|
+
import { performHttpRequestThroughFetch } from '../../../clients/fetch/index.js';
|
|
6
|
+
import { buildEntityRestAdapterMixins as adapterMixins } from '../build-entity-rest-adapter-mixins/index.js';
|
|
7
|
+
export const buildEntityRestAdapterLoad = (entityConstructor, { uriConfig })=>(request)=>Effect.gen(function*() {
|
|
8
|
+
var _metaEntity_key;
|
|
9
|
+
const configurationStore = yield* ConfigurationRepositoryTag;
|
|
10
|
+
const metaEntity = extractMetaEntity(entityConstructor);
|
|
11
|
+
const baseUrl = yield* adapterMixins.buildEntityBaseUrl(configurationStore, {
|
|
12
|
+
uriConfig
|
|
13
|
+
}, (_metaEntity_key = metaEntity.key) != null ? _metaEntity_key : metaEntity.name);
|
|
14
|
+
// Filtering goes out as RSQL and sorting as `sort` — the shared query
|
|
15
|
+
// protocol in core, so what this composes is exactly what the service
|
|
16
|
+
// parses back.
|
|
17
|
+
const query = serializeLoadRequestParams(request).toString();
|
|
18
|
+
const url = query ? `${baseUrl}?${query}` : baseUrl;
|
|
19
|
+
const response = yield* performHttpRequestThroughFetch(adapterMixins.buildEntityRequest({
|
|
20
|
+
method: 'GET',
|
|
21
|
+
url
|
|
22
|
+
}));
|
|
23
|
+
const page = yield* readEntityPageEnvelope(entityConstructor, response.body);
|
|
24
|
+
// The envelope echoes the request the service actually served; prefer the
|
|
25
|
+
// one this call made, which carries the caller's filtering/sorting types.
|
|
26
|
+
return _extends({}, page, {
|
|
27
|
+
request
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=build-entity-rest-adapter-load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-load/build-entity-rest-adapter-load.ts"],"sourcesContent":["import { ConfigurationRepositoryTag } from '@entifix/business';\nimport {\n Entity,\n EntityConstructor,\n EntityLoadRequest,\n EntityPage,\n extractMetaEntity,\n readEntityPageEnvelope,\n serializeLoadRequestParams,\n} from '@entifix/core';\nimport { Effect } from 'effect';\n\nimport { performHttpRequestThroughFetch } from '../../../clients/fetch/index.js';\nimport { buildEntityRestAdapterMixins as adapterMixins } from '../build-entity-rest-adapter-mixins/index.js';\nimport { BuildEntityRestOptions } from '../types.js';\n\nexport const buildEntityRestAdapterLoad =\n <TEntity extends Entity>(\n entityConstructor: EntityConstructor<TEntity>,\n { uriConfig }: BuildEntityRestOptions,\n ) =>\n <TEntity extends Entity>(request: EntityLoadRequest<TEntity>) =>\n Effect.gen(function* () {\n const configurationStore = yield* ConfigurationRepositoryTag;\n const metaEntity = extractMetaEntity(entityConstructor);\n\n const baseUrl = yield* adapterMixins.buildEntityBaseUrl(\n configurationStore,\n { uriConfig },\n metaEntity.key ?? metaEntity.name,\n );\n\n // Filtering goes out as RSQL and sorting as `sort` — the shared query\n // protocol in core, so what this composes is exactly what the service\n // parses back.\n const query = serializeLoadRequestParams(request).toString();\n const url = query ? `${baseUrl}?${query}` : baseUrl;\n\n const response = yield* performHttpRequestThroughFetch(\n adapterMixins.buildEntityRequest({ method: 'GET', url }),\n );\n const page = yield* readEntityPageEnvelope(\n entityConstructor,\n response.body,\n );\n\n // The envelope echoes the request the service actually served; prefer the\n // one this call made, which carries the caller's filtering/sorting types.\n return {\n ...page,\n request,\n } as unknown as EntityPage<TEntity>;\n });\n"],"names":["ConfigurationRepositoryTag","extractMetaEntity","readEntityPageEnvelope","serializeLoadRequestParams","Effect","performHttpRequestThroughFetch","buildEntityRestAdapterMixins","adapterMixins","buildEntityRestAdapterLoad","entityConstructor","uriConfig","request","gen","metaEntity","configurationStore","baseUrl","buildEntityBaseUrl","key","name","query","toString","url","response","buildEntityRequest","method","page","body"],"mappings":";AAAA,SAASA,0BAA0B,QAAQ,oBAAoB;AAC/D,SAKEC,iBAAiB,EACjBC,sBAAsB,EACtBC,0BAA0B,QACrB,gBAAgB;AACvB,SAASC,MAAM,QAAQ,SAAS;AAEhC,SAASC,8BAA8B,QAAQ,kCAAkC;AACjF,SAASC,gCAAgCC,aAAa,QAAQ,+CAA+C;AAG7G,OAAO,MAAMC,6BACX,CACEC,mBACA,EAAEC,SAAS,EAA0B,GAEvC,CAAyBC,UACvBP,OAAOQ,GAAG,CAAC;gBAOPC;YANF,MAAMC,qBAAqB,OAAOd;YAClC,MAAMa,aAAaZ,kBAAkBQ;YAErC,MAAMM,UAAU,OAAOR,cAAcS,kBAAkB,CACrDF,oBACA;gBAAEJ;YAAU,IACZG,kBAAAA,WAAWI,GAAG,YAAdJ,kBAAkBA,WAAWK,IAAI;YAGnC,sEAAsE;YACtE,sEAAsE;YACtE,eAAe;YACf,MAAMC,QAAQhB,2BAA2BQ,SAASS,QAAQ;YAC1D,MAAMC,MAAMF,QAAQ,GAAGJ,QAAQ,CAAC,EAAEI,OAAO,GAAGJ;YAE5C,MAAMO,WAAW,OAAOjB,+BACtBE,cAAcgB,kBAAkB,CAAC;gBAAEC,QAAQ;gBAAOH;YAAI;YAExD,MAAMI,OAAO,OAAOvB,uBAClBO,mBACAa,SAASI,IAAI;YAGf,0EAA0E;YAC1E,0EAA0E;YAC1E,OAAO,aACFD;gBACHd;;QAEJ,GAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-load/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-load/index.ts"],"sourcesContent":["export * from './build-entity-rest-adapter-load.js';\n"],"names":[],"mappings":"AAAA,cAAc,sCAAsC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ConfigurationClient } from '@entifix/core';
|
|
2
|
+
import { Effect } from 'effect';
|
|
3
|
+
import { BuildEntityRestOptions } from '../types.js';
|
|
4
|
+
export declare const buildEntityBaseUrl: (configurationStore: ConfigurationClient, options: BuildEntityRestOptions, entityName: string, entityId?: string) => Effect.Effect<string, import("@entifix/core").EntifixBuildError, never>;
|
|
5
|
+
//# sourceMappingURL=build-entity-base-url.d.ts.map
|
package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-base-url.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-entity-base-url.d.ts","sourceRoot":"","sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-base-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAIrD,eAAO,MAAM,kBAAkB,GAC7B,oBAAoB,mBAAmB,EACvC,SAAS,sBAAsB,EAC/B,YAAY,MAAM,EAClB,WAAW,MAAM,4EAYf,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
const DEFAULT_URI_GROUP = 'restUri';
|
|
3
|
+
export const buildEntityBaseUrl = (configurationStore, options, entityName, entityId)=>Effect.gen(function*() {
|
|
4
|
+
var _uriConfig_group;
|
|
5
|
+
const { uriConfig } = options;
|
|
6
|
+
const entityUri = yield* configurationStore.in((_uriConfig_group = uriConfig.group) != null ? _uriConfig_group : DEFAULT_URI_GROUP).getString(uriConfig.key.replace('[entity]', entityName), uriConfig.extractionMode);
|
|
7
|
+
return entityId ? `${entityUri}/${entityId}` : entityUri;
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=build-entity-base-url.js.map
|
package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-base-url.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-base-url.ts"],"sourcesContent":["import { ConfigurationClient } from '@entifix/core';\nimport { Effect } from 'effect';\n\nimport { BuildEntityRestOptions } from '../types.js';\n\nconst DEFAULT_URI_GROUP = 'restUri';\n\nexport const buildEntityBaseUrl = (\n configurationStore: ConfigurationClient,\n options: BuildEntityRestOptions,\n entityName: string,\n entityId?: string,\n) =>\n Effect.gen(function* () {\n const { uriConfig } = options;\n const entityUri = yield* configurationStore\n .in(uriConfig.group ?? DEFAULT_URI_GROUP)\n .getString(\n uriConfig.key.replace('[entity]', entityName),\n uriConfig.extractionMode,\n );\n\n return entityId ? `${entityUri}/${entityId}` : entityUri;\n });\n"],"names":["Effect","DEFAULT_URI_GROUP","buildEntityBaseUrl","configurationStore","options","entityName","entityId","gen","uriConfig","entityUri","in","group","getString","key","replace","extractionMode"],"mappings":"AACA,SAASA,MAAM,QAAQ,SAAS;AAIhC,MAAMC,oBAAoB;AAE1B,OAAO,MAAMC,qBAAqB,CAChCC,oBACAC,SACAC,YACAC,WAEAN,OAAOO,GAAG,CAAC;YAGHC;QAFN,MAAM,EAAEA,SAAS,EAAE,GAAGJ;QACtB,MAAMK,YAAY,OAAON,mBACtBO,EAAE,EAACF,mBAAAA,UAAUG,KAAK,YAAfH,mBAAmBP,mBACtBW,SAAS,CACRJ,UAAUK,GAAG,CAACC,OAAO,CAAC,YAAYT,aAClCG,UAAUO,cAAc;QAG5B,OAAOT,WAAW,GAAGG,UAAU,CAAC,EAAEH,UAAU,GAAGG;IACjD,GAAG"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { EntifixEnvelope } from '@entifix/core';
|
|
2
|
+
import { HttpMethod, HttpRequest } from '../../../clients/types.js';
|
|
3
|
+
export interface BuildEntityRequestOptions {
|
|
4
|
+
method: HttpMethod;
|
|
5
|
+
url: string;
|
|
6
|
+
/**
|
|
7
|
+
* The body, already wrapped as an envelope — every entifix message is one.
|
|
8
|
+
* Omitted for reads and deletes, which carry no payload.
|
|
9
|
+
*/
|
|
10
|
+
envelope?: EntifixEnvelope<unknown>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Assembles the {@link HttpRequest} the fetch client executes. Centralized so
|
|
14
|
+
* the read and write adapters agree on how a message is framed — notably that a
|
|
15
|
+
* body is always an {@link EntifixEnvelope}, and that the JSON content type is
|
|
16
|
+
* declared only when there is one to declare.
|
|
17
|
+
*/
|
|
18
|
+
export declare const buildEntityRequest: ({ method, url, envelope, }: BuildEntityRequestOptions) => HttpRequest<EntifixEnvelope<unknown>>;
|
|
19
|
+
//# sourceMappingURL=build-entity-request.d.ts.map
|
package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-request.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-entity-request.d.ts","sourceRoot":"","sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;CACrC;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,4BAIhC,yBAAyB,KAAG,WAAW,CAAC,eAAe,CAAC,OAAO,CAAC,CAMjE,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
/**
|
|
3
|
+
* Assembles the {@link HttpRequest} the fetch client executes. Centralized so
|
|
4
|
+
* the read and write adapters agree on how a message is framed — notably that a
|
|
5
|
+
* body is always an {@link EntifixEnvelope}, and that the JSON content type is
|
|
6
|
+
* declared only when there is one to declare.
|
|
7
|
+
*/ export const buildEntityRequest = ({ method, url, envelope })=>_extends({
|
|
8
|
+
method,
|
|
9
|
+
url
|
|
10
|
+
}, envelope ? {
|
|
11
|
+
headers: {
|
|
12
|
+
'Content-Type': 'application/json'
|
|
13
|
+
},
|
|
14
|
+
body: envelope
|
|
15
|
+
} : {});
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=build-entity-request.js.map
|
package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-request.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-request.ts"],"sourcesContent":["import type { EntifixEnvelope } from '@entifix/core';\n\nimport { HttpMethod, HttpRequest } from '../../../clients/types.js';\n\nexport interface BuildEntityRequestOptions {\n method: HttpMethod;\n url: string;\n /**\n * The body, already wrapped as an envelope — every entifix message is one.\n * Omitted for reads and deletes, which carry no payload.\n */\n envelope?: EntifixEnvelope<unknown>;\n}\n\n/**\n * Assembles the {@link HttpRequest} the fetch client executes. Centralized so\n * the read and write adapters agree on how a message is framed — notably that a\n * body is always an {@link EntifixEnvelope}, and that the JSON content type is\n * declared only when there is one to declare.\n */\nexport const buildEntityRequest = ({\n method,\n url,\n envelope,\n}: BuildEntityRequestOptions): HttpRequest<EntifixEnvelope<unknown>> => ({\n method,\n url,\n ...(envelope\n ? { headers: { 'Content-Type': 'application/json' }, body: envelope }\n : {}),\n});\n"],"names":["buildEntityRequest","method","url","envelope","headers","body"],"mappings":";AAcA;;;;;CAKC,GACD,OAAO,MAAMA,qBAAqB,CAAC,EACjCC,MAAM,EACNC,GAAG,EACHC,QAAQ,EACkB,GAA6C;QACvEF;QACAC;OACIC,WACA;QAAEC,SAAS;YAAE,gBAAgB;QAAmB;QAAGC,MAAMF;IAAS,IAClE,CAAC,GACJ"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const buildEntityRestAdapterMixins: {
|
|
2
|
+
buildEntityBaseUrl: (configurationStore: import("@entifix/core").ConfigurationClient, options: import("../types.js").BuildEntityRestOptions, entityName: string, entityId?: string) => import("effect/Effect").Effect<string, import("@entifix/core").EntifixBuildError, never>;
|
|
3
|
+
buildEntityRequest: ({ method, url, envelope, }: import("./build-entity-request.js").BuildEntityRequestOptions) => import("../../../index.js").HttpRequest<import("@entifix/core").EntifixEnvelope<unknown>>;
|
|
4
|
+
};
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-mixins/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,4BAA4B;;;CAGxC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-mixins/index.ts"],"sourcesContent":["import { buildEntityBaseUrl } from './build-entity-base-url.js';\nimport { buildEntityRequest } from './build-entity-request.js';\n\nexport const buildEntityRestAdapterMixins = {\n buildEntityBaseUrl,\n buildEntityRequest,\n};\n"],"names":["buildEntityBaseUrl","buildEntityRequest","buildEntityRestAdapterMixins"],"mappings":"AAAA,SAASA,kBAAkB,QAAQ,6BAA6B;AAChE,SAASC,kBAAkB,QAAQ,4BAA4B;AAE/D,OAAO,MAAMC,+BAA+B;IAC1CF;IACAC;AACF,EAAE"}
|
package/dist/adapters/entity-rest/build-entity-rest-adapter-save/build-entity-rest-adapter-save.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ConfigurationRepositoryTag } from '@entifix/business';
|
|
2
|
+
import { Entity, EntityConstructor } from '@entifix/core';
|
|
3
|
+
import { Effect } from 'effect';
|
|
4
|
+
import { BuildEntityRestOptions } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Persists an entity over HTTP.
|
|
7
|
+
*
|
|
8
|
+
* An entity without an id has never been stored, so it is created with `POST`
|
|
9
|
+
* against the collection; one with an id is replaced with `PUT` against its own
|
|
10
|
+
* URL.
|
|
11
|
+
*
|
|
12
|
+
* For a plain create the response envelope — not the request — is what gets
|
|
13
|
+
* deserialized and returned, because the service is the authority on the stored
|
|
14
|
+
* entity (it assigns ids and may normalize fields).
|
|
15
|
+
*
|
|
16
|
+
* A **transactional** create inverts that, and deliberately. The service answers
|
|
17
|
+
* `202` describing a transaction rather than an entity, so there is no stored
|
|
18
|
+
* entity to read back yet: the client mints the transaction id, which *is* the
|
|
19
|
+
* id the entity will be stored under, and returns the entity it already holds.
|
|
20
|
+
* That is the point of the client owning the id (ADR 0028) — before it, this
|
|
21
|
+
* adapter parsed the `202` as an entity envelope, failed, and reported an error
|
|
22
|
+
* for a create that was in fact about to succeed.
|
|
23
|
+
*/
|
|
24
|
+
export declare const buildEntityRestAdapterSave: <TEntity extends Entity>(entityConstructor: EntityConstructor<TEntity>, { uriConfig, create }: BuildEntityRestOptions) => <TInput extends Entity>(entity: TInput) => Effect.Effect<TInput, import("@entifix/core").EntifixError, ConfigurationRepositoryTag>;
|
|
25
|
+
//# sourceMappingURL=build-entity-rest-adapter-save.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-entity-rest-adapter-save.d.ts","sourceRoot":"","sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-save/build-entity-rest-adapter-save.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EACL,MAAM,EACN,iBAAiB,EAKlB,MAAM,eAAe,CAAC;AAOvB,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AAIxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAErD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,0BAA0B,GACpC,OAAO,SAAS,MAAM,EACrB,mBAAmB,iBAAiB,CAAC,OAAO,CAAC,EAC7C,uBAAkC,sBAAsB,MAKzD,MAAM,SAAS,MAAM,EAAE,QAAQ,MAAM,4FAkFlC,CAAC"}
|
package/dist/adapters/entity-rest/build-entity-rest-adapter-save/build-entity-rest-adapter-save.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { ConfigurationRepositoryTag } from '@entifix/business';
|
|
2
|
+
import { extractMetaEntity, makeEntityEnvelope, readEntityEnvelope, serializeEntity } from '@entifix/core';
|
|
3
|
+
import { makeCommandEnvelope, readTransactionAcceptedEnvelope, TransactionSinkTag } from '@entifix/transactions';
|
|
4
|
+
import { Effect, Option } from 'effect';
|
|
5
|
+
import { performHttpRequestThroughFetch } from '../../../clients/fetch/index.js';
|
|
6
|
+
import { buildEntityRestAdapterMixins as adapterMixins } from '../build-entity-rest-adapter-mixins/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Persists an entity over HTTP.
|
|
9
|
+
*
|
|
10
|
+
* An entity without an id has never been stored, so it is created with `POST`
|
|
11
|
+
* against the collection; one with an id is replaced with `PUT` against its own
|
|
12
|
+
* URL.
|
|
13
|
+
*
|
|
14
|
+
* For a plain create the response envelope — not the request — is what gets
|
|
15
|
+
* deserialized and returned, because the service is the authority on the stored
|
|
16
|
+
* entity (it assigns ids and may normalize fields).
|
|
17
|
+
*
|
|
18
|
+
* A **transactional** create inverts that, and deliberately. The service answers
|
|
19
|
+
* `202` describing a transaction rather than an entity, so there is no stored
|
|
20
|
+
* entity to read back yet: the client mints the transaction id, which *is* the
|
|
21
|
+
* id the entity will be stored under, and returns the entity it already holds.
|
|
22
|
+
* That is the point of the client owning the id (ADR 0028) — before it, this
|
|
23
|
+
* adapter parsed the `202` as an entity envelope, failed, and reported an error
|
|
24
|
+
* for a create that was in fact about to succeed.
|
|
25
|
+
*/ export const buildEntityRestAdapterSave = (entityConstructor, { uriConfig, create = 'entity' })=>// Deliberately not shadowing `TEntity` here (as the read builders do): the
|
|
26
|
+
// envelope has to be built against the *constructor's* entity type, which a
|
|
27
|
+
// shadowed parameter would make unreachable.
|
|
28
|
+
(entity)=>Effect.gen(function*() {
|
|
29
|
+
var _metaEntity_key;
|
|
30
|
+
const configurationStore = yield* ConfigurationRepositoryTag;
|
|
31
|
+
const metaEntity = extractMetaEntity(entityConstructor);
|
|
32
|
+
const key = (_metaEntity_key = metaEntity.key) != null ? _metaEntity_key : metaEntity.name;
|
|
33
|
+
const isCreate = entity.id == null;
|
|
34
|
+
const url = yield* adapterMixins.buildEntityBaseUrl(configurationStore, {
|
|
35
|
+
uriConfig
|
|
36
|
+
}, key, isCreate ? undefined : String(entity.id));
|
|
37
|
+
if (isCreate && create === 'command') {
|
|
38
|
+
// `crypto.randomUUID` is available in every browser this ships to and in
|
|
39
|
+
// Node — and the id must be a UUID, because the service constrains the
|
|
40
|
+
// key space a caller may address.
|
|
41
|
+
const transactionId = crypto.randomUUID();
|
|
42
|
+
entity.id = transactionId;
|
|
43
|
+
const command = {
|
|
44
|
+
transactionId,
|
|
45
|
+
type: 'create',
|
|
46
|
+
entity: key,
|
|
47
|
+
payload: serializeEntity(entityConstructor, entity)
|
|
48
|
+
};
|
|
49
|
+
const accepted = yield* performHttpRequestThroughFetch(adapterMixins.buildEntityRequest({
|
|
50
|
+
method: 'POST',
|
|
51
|
+
url,
|
|
52
|
+
envelope: makeCommandEnvelope(command)
|
|
53
|
+
}));
|
|
54
|
+
// Read for its shape, not its contents: this asserts the service really
|
|
55
|
+
// accepted a transaction rather than answering something else with a
|
|
56
|
+
// 2xx, which is the failure the old code path could not distinguish.
|
|
57
|
+
yield* readTransactionAcceptedEnvelope(accepted.body);
|
|
58
|
+
// Tell whoever is watching that a write is in flight. This is the only
|
|
59
|
+
// point in the system that knows it — the entity returned below is
|
|
60
|
+
// indistinguishable from a plain REST create, so without this the
|
|
61
|
+
// browser navigates away at the `202` and a later failure leaves no row,
|
|
62
|
+
// no message and nothing to retry from (ADR 0043).
|
|
63
|
+
//
|
|
64
|
+
// `serviceOption`, deliberately: reading the tag this way keeps it out
|
|
65
|
+
// of this function's `R`, so the storefront, the plain REST adapters and
|
|
66
|
+
// every existing spec compile and run with no layer to provide. The cost
|
|
67
|
+
// is that nothing *forces* a composition root to provide it, which is
|
|
68
|
+
// why `mergeContext` has a spec pinning that it does.
|
|
69
|
+
const sink = yield* Effect.serviceOption(TransactionSinkTag);
|
|
70
|
+
if (Option.isSome(sink)) {
|
|
71
|
+
// After the assertion above, never before: a `2xx` that is not a
|
|
72
|
+
// transaction envelope must not register a pending id, because nothing
|
|
73
|
+
// would ever settle it and the entry becomes a permanent phantom.
|
|
74
|
+
sink.value.began({
|
|
75
|
+
transactionId,
|
|
76
|
+
entity: key,
|
|
77
|
+
at: new Date().toISOString()
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return entity;
|
|
81
|
+
}
|
|
82
|
+
const httpRequest = adapterMixins.buildEntityRequest({
|
|
83
|
+
method: isCreate ? 'POST' : 'PUT',
|
|
84
|
+
url,
|
|
85
|
+
envelope: makeEntityEnvelope(entityConstructor, entity)
|
|
86
|
+
});
|
|
87
|
+
const response = yield* performHttpRequestThroughFetch(httpRequest);
|
|
88
|
+
const saved = yield* readEntityEnvelope(entityConstructor, response.body);
|
|
89
|
+
return saved;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
//# sourceMappingURL=build-entity-rest-adapter-save.js.map
|