@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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +11 -0
  3. package/dist/adapters/entity-metadata/make-entity-metadata-source/index.d.ts +2 -0
  4. package/dist/adapters/entity-metadata/make-entity-metadata-source/index.d.ts.map +1 -0
  5. package/dist/adapters/entity-metadata/make-entity-metadata-source/index.js +3 -0
  6. package/dist/adapters/entity-metadata/make-entity-metadata-source/index.js.map +1 -0
  7. package/dist/adapters/entity-metadata/make-entity-metadata-source/make-entity-metadata-source.d.ts +23 -0
  8. package/dist/adapters/entity-metadata/make-entity-metadata-source/make-entity-metadata-source.d.ts.map +1 -0
  9. package/dist/adapters/entity-metadata/make-entity-metadata-source/make-entity-metadata-source.js +45 -0
  10. package/dist/adapters/entity-metadata/make-entity-metadata-source/make-entity-metadata-source.js.map +1 -0
  11. package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/build-entity-rest-adapter-delete.d.ts +13 -0
  12. package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/build-entity-rest-adapter-delete.d.ts.map +1 -0
  13. package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/build-entity-rest-adapter-delete.js +34 -0
  14. package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/build-entity-rest-adapter-delete.js.map +1 -0
  15. package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/index.d.ts +2 -0
  16. package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/index.d.ts.map +1 -0
  17. package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/index.js +3 -0
  18. package/dist/adapters/entity-rest/build-entity-rest-adapter-delete/index.js.map +1 -0
  19. package/dist/adapters/entity-rest/build-entity-rest-adapter-get/build-entity-rest-adapter-get.d.ts +6 -0
  20. package/dist/adapters/entity-rest/build-entity-rest-adapter-get/build-entity-rest-adapter-get.d.ts.map +1 -0
  21. package/dist/adapters/entity-rest/build-entity-rest-adapter-get/build-entity-rest-adapter-get.js +21 -0
  22. package/dist/adapters/entity-rest/build-entity-rest-adapter-get/build-entity-rest-adapter-get.js.map +1 -0
  23. package/dist/adapters/entity-rest/build-entity-rest-adapter-get/index.d.ts +2 -0
  24. package/dist/adapters/entity-rest/build-entity-rest-adapter-get/index.d.ts.map +1 -0
  25. package/dist/adapters/entity-rest/build-entity-rest-adapter-get/index.js +3 -0
  26. package/dist/adapters/entity-rest/build-entity-rest-adapter-get/index.js.map +1 -0
  27. package/dist/adapters/entity-rest/build-entity-rest-adapter-load/build-entity-rest-adapter-load.d.ts +6 -0
  28. package/dist/adapters/entity-rest/build-entity-rest-adapter-load/build-entity-rest-adapter-load.d.ts.map +1 -0
  29. package/dist/adapters/entity-rest/build-entity-rest-adapter-load/build-entity-rest-adapter-load.js +31 -0
  30. package/dist/adapters/entity-rest/build-entity-rest-adapter-load/build-entity-rest-adapter-load.js.map +1 -0
  31. package/dist/adapters/entity-rest/build-entity-rest-adapter-load/index.d.ts +2 -0
  32. package/dist/adapters/entity-rest/build-entity-rest-adapter-load/index.d.ts.map +1 -0
  33. package/dist/adapters/entity-rest/build-entity-rest-adapter-load/index.js +3 -0
  34. package/dist/adapters/entity-rest/build-entity-rest-adapter-load/index.js.map +1 -0
  35. package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-base-url.d.ts +5 -0
  36. package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-base-url.d.ts.map +1 -0
  37. package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-base-url.js +10 -0
  38. package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-base-url.js.map +1 -0
  39. package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-request.d.ts +19 -0
  40. package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-request.d.ts.map +1 -0
  41. package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-request.js +17 -0
  42. package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/build-entity-request.js.map +1 -0
  43. package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/index.d.ts +5 -0
  44. package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/index.d.ts.map +1 -0
  45. package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/index.js +8 -0
  46. package/dist/adapters/entity-rest/build-entity-rest-adapter-mixins/index.js.map +1 -0
  47. package/dist/adapters/entity-rest/build-entity-rest-adapter-save/build-entity-rest-adapter-save.d.ts +25 -0
  48. package/dist/adapters/entity-rest/build-entity-rest-adapter-save/build-entity-rest-adapter-save.d.ts.map +1 -0
  49. package/dist/adapters/entity-rest/build-entity-rest-adapter-save/build-entity-rest-adapter-save.js +92 -0
  50. package/dist/adapters/entity-rest/build-entity-rest-adapter-save/build-entity-rest-adapter-save.js.map +1 -0
  51. package/dist/adapters/entity-rest/build-entity-rest-adapter-save/index.d.ts +2 -0
  52. package/dist/adapters/entity-rest/build-entity-rest-adapter-save/index.d.ts.map +1 -0
  53. package/dist/adapters/entity-rest/build-entity-rest-adapter-save/index.js +3 -0
  54. package/dist/adapters/entity-rest/build-entity-rest-adapter-save/index.js.map +1 -0
  55. package/dist/adapters/entity-rest/types.d.ts +24 -0
  56. package/dist/adapters/entity-rest/types.d.ts.map +1 -0
  57. package/dist/adapters/entity-rest/types.js +3 -0
  58. package/dist/adapters/entity-rest/types.js.map +1 -0
  59. package/dist/adapters/transaction-status/build-transaction-status-reader/build-transaction-status-reader.d.ts +23 -0
  60. package/dist/adapters/transaction-status/build-transaction-status-reader/build-transaction-status-reader.d.ts.map +1 -0
  61. package/dist/adapters/transaction-status/build-transaction-status-reader/build-transaction-status-reader.js +45 -0
  62. package/dist/adapters/transaction-status/build-transaction-status-reader/build-transaction-status-reader.js.map +1 -0
  63. package/dist/adapters/transaction-status/build-transaction-status-reader/index.d.ts +2 -0
  64. package/dist/adapters/transaction-status/build-transaction-status-reader/index.d.ts.map +1 -0
  65. package/dist/adapters/transaction-status/build-transaction-status-reader/index.js +3 -0
  66. package/dist/adapters/transaction-status/build-transaction-status-reader/index.js.map +1 -0
  67. package/dist/clients/fetch/fetch-client.d.ts +5 -0
  68. package/dist/clients/fetch/fetch-client.d.ts.map +1 -0
  69. package/dist/clients/fetch/fetch-client.js +53 -0
  70. package/dist/clients/fetch/fetch-client.js.map +1 -0
  71. package/dist/clients/fetch/index.d.ts +2 -0
  72. package/dist/clients/fetch/index.d.ts.map +1 -0
  73. package/dist/clients/fetch/index.js +3 -0
  74. package/dist/clients/fetch/index.js.map +1 -0
  75. package/dist/clients/types.d.ts +14 -0
  76. package/dist/clients/types.d.ts.map +1 -0
  77. package/dist/clients/types.js +3 -0
  78. package/dist/clients/types.js.map +1 -0
  79. package/dist/configuration-client/configuration-client-rest-client.d.ts +28 -0
  80. package/dist/configuration-client/configuration-client-rest-client.d.ts.map +1 -0
  81. package/dist/configuration-client/configuration-client-rest-client.js +94 -0
  82. package/dist/configuration-client/configuration-client-rest-client.js.map +1 -0
  83. package/dist/configuration-client/index.d.ts +2 -0
  84. package/dist/configuration-client/index.d.ts.map +1 -0
  85. package/dist/configuration-client/index.js +3 -0
  86. package/dist/configuration-client/index.js.map +1 -0
  87. package/dist/index.d.ts +11 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +12 -0
  90. package/dist/index.js.map +1 -0
  91. package/package.json +68 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-save/build-entity-rest-adapter-save.ts"],"sourcesContent":["import { ConfigurationRepositoryTag } from '@entifix/business';\nimport {\n Entity,\n EntityConstructor,\n extractMetaEntity,\n makeEntityEnvelope,\n readEntityEnvelope,\n serializeEntity,\n} from '@entifix/core';\nimport {\n makeCommandEnvelope,\n readTransactionAcceptedEnvelope,\n type TransactionCommand,\n TransactionSinkTag,\n} from '@entifix/transactions';\nimport { Effect, Option } 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/**\n * Persists an entity over HTTP.\n *\n * An entity without an id has never been stored, so it is created with `POST`\n * against the collection; one with an id is replaced with `PUT` against its own\n * URL.\n *\n * For a plain create the response envelope — not the request — is what gets\n * deserialized and returned, because the service is the authority on the stored\n * entity (it assigns ids and may normalize fields).\n *\n * A **transactional** create inverts that, and deliberately. The service answers\n * `202` describing a transaction rather than an entity, so there is no stored\n * entity to read back yet: the client mints the transaction id, which *is* the\n * id the entity will be stored under, and returns the entity it already holds.\n * That is the point of the client owning the id (ADR 0028) — before it, this\n * adapter parsed the `202` as an entity envelope, failed, and reported an error\n * for a create that was in fact about to succeed.\n */\nexport const buildEntityRestAdapterSave =\n <TEntity extends Entity>(\n entityConstructor: EntityConstructor<TEntity>,\n { uriConfig, create = 'entity' }: BuildEntityRestOptions,\n ) =>\n // Deliberately not shadowing `TEntity` here (as the read builders do): the\n // envelope has to be built against the *constructor's* entity type, which a\n // shadowed parameter would make unreachable.\n <TInput extends Entity>(entity: TInput) =>\n Effect.gen(function* () {\n const configurationStore = yield* ConfigurationRepositoryTag;\n const metaEntity = extractMetaEntity(entityConstructor);\n const key = metaEntity.key ?? metaEntity.name;\n const isCreate = entity.id == null;\n\n const url = yield* adapterMixins.buildEntityBaseUrl(\n configurationStore,\n { uriConfig },\n key,\n isCreate ? undefined : String(entity.id),\n );\n\n if (isCreate && create === 'command') {\n // `crypto.randomUUID` is available in every browser this ships to and in\n // Node — and the id must be a UUID, because the service constrains the\n // key space a caller may address.\n const transactionId = crypto.randomUUID();\n entity.id = transactionId;\n\n const command: TransactionCommand = {\n transactionId,\n type: 'create',\n entity: key,\n payload: serializeEntity(\n entityConstructor,\n entity as unknown as TEntity,\n ),\n };\n\n const accepted = yield* performHttpRequestThroughFetch(\n adapterMixins.buildEntityRequest({\n method: 'POST',\n url,\n envelope: makeCommandEnvelope(command),\n }),\n );\n // Read for its shape, not its contents: this asserts the service really\n // accepted a transaction rather than answering something else with a\n // 2xx, which is the failure the old code path could not distinguish.\n yield* readTransactionAcceptedEnvelope(accepted.body);\n\n // Tell whoever is watching that a write is in flight. This is the only\n // point in the system that knows it — the entity returned below is\n // indistinguishable from a plain REST create, so without this the\n // browser navigates away at the `202` and a later failure leaves no row,\n // no message and nothing to retry from (ADR 0043).\n //\n // `serviceOption`, deliberately: reading the tag this way keeps it out\n // of this function's `R`, so the storefront, the plain REST adapters and\n // every existing spec compile and run with no layer to provide. The cost\n // is that nothing *forces* a composition root to provide it, which is\n // why `mergeContext` has a spec pinning that it does.\n const sink = yield* Effect.serviceOption(TransactionSinkTag);\n if (Option.isSome(sink)) {\n // After the assertion above, never before: a `2xx` that is not a\n // transaction envelope must not register a pending id, because nothing\n // would ever settle it and the entry becomes a permanent phantom.\n sink.value.began({\n transactionId,\n entity: key,\n at: new Date().toISOString(),\n });\n }\n\n return entity;\n }\n\n const httpRequest = adapterMixins.buildEntityRequest({\n method: isCreate ? 'POST' : 'PUT',\n url,\n envelope: makeEntityEnvelope(\n entityConstructor,\n entity as unknown as TEntity,\n ),\n });\n\n const response = yield* performHttpRequestThroughFetch(httpRequest);\n const saved = yield* readEntityEnvelope(entityConstructor, response.body);\n\n return saved as unknown as TInput;\n });\n"],"names":["ConfigurationRepositoryTag","extractMetaEntity","makeEntityEnvelope","readEntityEnvelope","serializeEntity","makeCommandEnvelope","readTransactionAcceptedEnvelope","TransactionSinkTag","Effect","Option","performHttpRequestThroughFetch","buildEntityRestAdapterMixins","adapterMixins","buildEntityRestAdapterSave","entityConstructor","uriConfig","create","entity","gen","metaEntity","configurationStore","key","name","isCreate","id","url","buildEntityBaseUrl","undefined","String","transactionId","crypto","randomUUID","command","type","payload","accepted","buildEntityRequest","method","envelope","body","sink","serviceOption","isSome","value","began","at","Date","toISOString","httpRequest","response","saved"],"mappings":"AAAA,SAASA,0BAA0B,QAAQ,oBAAoB;AAC/D,SAGEC,iBAAiB,EACjBC,kBAAkB,EAClBC,kBAAkB,EAClBC,eAAe,QACV,gBAAgB;AACvB,SACEC,mBAAmB,EACnBC,+BAA+B,EAE/BC,kBAAkB,QACb,wBAAwB;AAC/B,SAASC,MAAM,EAAEC,MAAM,QAAQ,SAAS;AAExC,SAASC,8BAA8B,QAAQ,kCAAkC;AACjF,SAASC,gCAAgCC,aAAa,QAAQ,+CAA+C;AAG7G;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,MAAMC,6BACX,CACEC,mBACA,EAAEC,SAAS,EAAEC,SAAS,QAAQ,EAA0B,GAE1D,2EAA2E;IAC3E,4EAA4E;IAC5E,6CAA6C;IAC7C,CAAwBC,SACtBT,OAAOU,GAAG,CAAC;gBAGGC;YAFZ,MAAMC,qBAAqB,OAAOpB;YAClC,MAAMmB,aAAalB,kBAAkBa;YACrC,MAAMO,OAAMF,kBAAAA,WAAWE,GAAG,YAAdF,kBAAkBA,WAAWG,IAAI;YAC7C,MAAMC,WAAWN,OAAOO,EAAE,IAAI;YAE9B,MAAMC,MAAM,OAAOb,cAAcc,kBAAkB,CACjDN,oBACA;gBAAEL;YAAU,GACZM,KACAE,WAAWI,YAAYC,OAAOX,OAAOO,EAAE;YAGzC,IAAID,YAAYP,WAAW,WAAW;gBACpC,yEAAyE;gBACzE,uEAAuE;gBACvE,kCAAkC;gBAClC,MAAMa,gBAAgBC,OAAOC,UAAU;gBACvCd,OAAOO,EAAE,GAAGK;gBAEZ,MAAMG,UAA8B;oBAClCH;oBACAI,MAAM;oBACNhB,QAAQI;oBACRa,SAAS9B,gBACPU,mBACAG;gBAEJ;gBAEA,MAAMkB,WAAW,OAAOzB,+BACtBE,cAAcwB,kBAAkB,CAAC;oBAC/BC,QAAQ;oBACRZ;oBACAa,UAAUjC,oBAAoB2B;gBAChC;gBAEF,wEAAwE;gBACxE,qEAAqE;gBACrE,qEAAqE;gBACrE,OAAO1B,gCAAgC6B,SAASI,IAAI;gBAEpD,uEAAuE;gBACvE,mEAAmE;gBACnE,kEAAkE;gBAClE,yEAAyE;gBACzE,mDAAmD;gBACnD,EAAE;gBACF,uEAAuE;gBACvE,yEAAyE;gBACzE,yEAAyE;gBACzE,sEAAsE;gBACtE,sDAAsD;gBACtD,MAAMC,OAAO,OAAOhC,OAAOiC,aAAa,CAAClC;gBACzC,IAAIE,OAAOiC,MAAM,CAACF,OAAO;oBACvB,iEAAiE;oBACjE,uEAAuE;oBACvE,kEAAkE;oBAClEA,KAAKG,KAAK,CAACC,KAAK,CAAC;wBACff;wBACAZ,QAAQI;wBACRwB,IAAI,IAAIC,OAAOC,WAAW;oBAC5B;gBACF;gBAEA,OAAO9B;YACT;YAEA,MAAM+B,cAAcpC,cAAcwB,kBAAkB,CAAC;gBACnDC,QAAQd,WAAW,SAAS;gBAC5BE;gBACAa,UAAUpC,mBACRY,mBACAG;YAEJ;YAEA,MAAMgC,WAAW,OAAOvC,+BAA+BsC;YACvD,MAAME,QAAQ,OAAO/C,mBAAmBW,mBAAmBmC,SAASV,IAAI;YAExE,OAAOW;QACT,GAAG"}
@@ -0,0 +1,2 @@
1
+ export * from './build-entity-rest-adapter-save.js';
2
+ //# 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-save/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './build-entity-rest-adapter-save.js';
2
+
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/adapters/entity-rest/build-entity-rest-adapter-save/index.ts"],"sourcesContent":["export * from './build-entity-rest-adapter-save.js';\n"],"names":[],"mappings":"AAAA,cAAc,sCAAsC"}
@@ -0,0 +1,24 @@
1
+ import { ConfigurationExtractMode } from '@entifix/core';
2
+ /**
3
+ * How a create is sent to this entity's service.
4
+ *
5
+ * `entity` is the plain REST write: `POST` an entity envelope, get the stored
6
+ * entity back. `command` is the CQRS write path — the client mints the
7
+ * transaction id, `POST`s a `command` envelope and gets a `202` naming the
8
+ * transaction, because the write completes asynchronously behind a saga.
9
+ *
10
+ * It is per entity rather than global because the two live side by side today:
11
+ * `ProductSpecification` is transactional, while `ProductBrand` and
12
+ * `ProductCategory` are plain writes on another service.
13
+ */
14
+ export type EntityCreateProtocol = 'entity' | 'command';
15
+ export interface BuildEntityRestOptions {
16
+ uriConfig: {
17
+ key: string;
18
+ group?: string;
19
+ extractionMode?: ConfigurationExtractMode;
20
+ };
21
+ /** Defaults to `'entity'` — the plain REST write. */
22
+ create?: EntityCreateProtocol;
23
+ }
24
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/adapters/entity-rest/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAExD,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE;QACT,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,wBAAwB,CAAC;KAC3C,CAAC;IACF,qDAAqD;IACrD,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B"}
@@ -0,0 +1,3 @@
1
+ export { };
2
+
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/entity-rest/types.ts"],"sourcesContent":["import { ConfigurationExtractMode } from '@entifix/core';\n\n/**\n * How a create is sent to this entity's service.\n *\n * `entity` is the plain REST write: `POST` an entity envelope, get the stored\n * entity back. `command` is the CQRS write path — the client mints the\n * transaction id, `POST`s a `command` envelope and gets a `202` naming the\n * transaction, because the write completes asynchronously behind a saga.\n *\n * It is per entity rather than global because the two live side by side today:\n * `ProductSpecification` is transactional, while `ProductBrand` and\n * `ProductCategory` are plain writes on another service.\n */\nexport type EntityCreateProtocol = 'entity' | 'command';\n\nexport interface BuildEntityRestOptions {\n uriConfig: {\n key: string;\n group?: string;\n extractionMode?: ConfigurationExtractMode;\n };\n /** Defaults to `'entity'` — the plain REST write. */\n create?: EntityCreateProtocol;\n}\n"],"names":[],"mappings":"AAgBA,WAQC"}
@@ -0,0 +1,23 @@
1
+ import { ConfigurationRepositoryTag } from '@entifix/business';
2
+ import { type TransactionStatusReader } from '@entifix/transactions';
3
+ import { Effect } from 'effect';
4
+ import type { BuildEntityRestOptions } from '../../entity-rest/types.js';
5
+ /**
6
+ * Reads one transaction's record over HTTP, for a browser reconciling a write it
7
+ * started.
8
+ *
9
+ * ⚠️ **A `404` answers `undefined`, and that is not a failure.** `accepted`
10
+ * reaches the tracker over the bus, so with the broker down the entity write
11
+ * commits — the outbox is in the same Mongo transaction — while no event is ever
12
+ * published and the tracker holds no record at all. A caller that treated this
13
+ * as terminal would un-render a healthy write during a broker outage, which is
14
+ * the moment nobody can tell a UI bug from an outage (ADR 0043). The route also
15
+ * answers `404` for another tenant's record, deliberately, so it cannot be
16
+ * walked to probe ids that are also primary keys — indistinguishable here, and
17
+ * correctly so: neither is a record this caller may reconcile against.
18
+ *
19
+ * Every other status stays an error, so an unreachable service is not quietly
20
+ * read as "no such transaction".
21
+ */
22
+ export declare const buildTransactionStatusReader: (options: BuildEntityRestOptions) => Effect.Effect<TransactionStatusReader, never, ConfigurationRepositoryTag>;
23
+ //# sourceMappingURL=build-transaction-status-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-transaction-status-reader.d.ts","sourceRoot":"","sources":["../../../../src/adapters/transaction-status/build-transaction-status-reader/build-transaction-status-reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAE/D,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAUzE;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,4BAA4B,GACvC,SAAS,sBAAsB,KAC9B,MAAM,CAAC,MAAM,CAAC,uBAAuB,EAAE,KAAK,EAAE,0BAA0B,CA6BvE,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { ConfigurationRepositoryTag } from '@entifix/business';
2
+ import { readTransactionRecordEnvelope } from '@entifix/transactions';
3
+ import { Effect } from 'effect';
4
+ import { performHttpRequestThroughFetch } from '../../../clients/fetch/index.js';
5
+ import { buildEntityRestAdapterMixins as adapterMixins } from '../../entity-rest/build-entity-rest-adapter-mixins/index.js';
6
+ /**
7
+ * The tracker's own path segment. It is not an entity — nothing decorates a
8
+ * `TransactionRecord` — but the URL is composed the same way every entity URL
9
+ * is, so `buildEntityBaseUrl` (already generic over an arbitrary name) needs no
10
+ * transaction-shaped sibling.
11
+ */ const TRANSACTION_PATH = 'transaction';
12
+ /**
13
+ * Reads one transaction's record over HTTP, for a browser reconciling a write it
14
+ * started.
15
+ *
16
+ * ⚠️ **A `404` answers `undefined`, and that is not a failure.** `accepted`
17
+ * reaches the tracker over the bus, so with the broker down the entity write
18
+ * commits — the outbox is in the same Mongo transaction — while no event is ever
19
+ * published and the tracker holds no record at all. A caller that treated this
20
+ * as terminal would un-render a healthy write during a broker outage, which is
21
+ * the moment nobody can tell a UI bug from an outage (ADR 0043). The route also
22
+ * answers `404` for another tenant's record, deliberately, so it cannot be
23
+ * walked to probe ids that are also primary keys — indistinguishable here, and
24
+ * correctly so: neither is a record this caller may reconcile against.
25
+ *
26
+ * Every other status stays an error, so an unreachable service is not quietly
27
+ * read as "no such transaction".
28
+ */ export const buildTransactionStatusReader = (options)=>Effect.gen(function*() {
29
+ const configurationStore = yield* ConfigurationRepositoryTag;
30
+ return {
31
+ read: (transactionId)=>Effect.gen(function*() {
32
+ const url = yield* adapterMixins.buildEntityBaseUrl(configurationStore, options, TRANSACTION_PATH, transactionId);
33
+ const response = yield* performHttpRequestThroughFetch(adapterMixins.buildEntityRequest({
34
+ method: 'GET',
35
+ url
36
+ }));
37
+ return yield* readTransactionRecordEnvelope(response.body);
38
+ }).pipe(Effect.catchAll((error)=>{
39
+ var _error_details;
40
+ return ((_error_details = error.details) == null ? void 0 : _error_details['status']) === 404 ? Effect.succeed(undefined) : Effect.fail(error);
41
+ }))
42
+ };
43
+ });
44
+
45
+ //# sourceMappingURL=build-transaction-status-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/adapters/transaction-status/build-transaction-status-reader/build-transaction-status-reader.ts"],"sourcesContent":["import { ConfigurationRepositoryTag } from '@entifix/business';\nimport type { EntifixError } from '@entifix/core';\nimport {\n readTransactionRecordEnvelope,\n type TransactionRecord,\n type TransactionStatusReader,\n} from '@entifix/transactions';\nimport { Effect } from 'effect';\n\nimport { performHttpRequestThroughFetch } from '../../../clients/fetch/index.js';\nimport { buildEntityRestAdapterMixins as adapterMixins } from '../../entity-rest/build-entity-rest-adapter-mixins/index.js';\nimport type { BuildEntityRestOptions } from '../../entity-rest/types.js';\n\n/**\n * The tracker's own path segment. It is not an entity — nothing decorates a\n * `TransactionRecord` — but the URL is composed the same way every entity URL\n * is, so `buildEntityBaseUrl` (already generic over an arbitrary name) needs no\n * transaction-shaped sibling.\n */\nconst TRANSACTION_PATH = 'transaction';\n\n/**\n * Reads one transaction's record over HTTP, for a browser reconciling a write it\n * started.\n *\n * ⚠️ **A `404` answers `undefined`, and that is not a failure.** `accepted`\n * reaches the tracker over the bus, so with the broker down the entity write\n * commits — the outbox is in the same Mongo transaction — while no event is ever\n * published and the tracker holds no record at all. A caller that treated this\n * as terminal would un-render a healthy write during a broker outage, which is\n * the moment nobody can tell a UI bug from an outage (ADR 0043). The route also\n * answers `404` for another tenant's record, deliberately, so it cannot be\n * walked to probe ids that are also primary keys — indistinguishable here, and\n * correctly so: neither is a record this caller may reconcile against.\n *\n * Every other status stays an error, so an unreachable service is not quietly\n * read as \"no such transaction\".\n */\nexport const buildTransactionStatusReader = (\n options: BuildEntityRestOptions,\n): Effect.Effect<TransactionStatusReader, never, ConfigurationRepositoryTag> =>\n Effect.gen(function* () {\n const configurationStore = yield* ConfigurationRepositoryTag;\n\n return {\n read: (\n transactionId: string,\n ): Effect.Effect<TransactionRecord | undefined, EntifixError> =>\n Effect.gen(function* () {\n const url = yield* adapterMixins.buildEntityBaseUrl(\n configurationStore,\n options,\n TRANSACTION_PATH,\n transactionId,\n );\n\n const response = yield* performHttpRequestThroughFetch(\n adapterMixins.buildEntityRequest({ method: 'GET', url }),\n );\n\n return yield* readTransactionRecordEnvelope(response.body);\n }).pipe(\n Effect.catchAll(error =>\n error.details?.['status'] === 404\n ? Effect.succeed(undefined)\n : Effect.fail(error),\n ),\n ),\n };\n });\n"],"names":["ConfigurationRepositoryTag","readTransactionRecordEnvelope","Effect","performHttpRequestThroughFetch","buildEntityRestAdapterMixins","adapterMixins","TRANSACTION_PATH","buildTransactionStatusReader","options","gen","configurationStore","read","transactionId","url","buildEntityBaseUrl","response","buildEntityRequest","method","body","pipe","catchAll","error","details","succeed","undefined","fail"],"mappings":"AAAA,SAASA,0BAA0B,QAAQ,oBAAoB;AAE/D,SACEC,6BAA6B,QAGxB,wBAAwB;AAC/B,SAASC,MAAM,QAAQ,SAAS;AAEhC,SAASC,8BAA8B,QAAQ,kCAAkC;AACjF,SAASC,gCAAgCC,aAAa,QAAQ,8DAA8D;AAG5H;;;;;CAKC,GACD,MAAMC,mBAAmB;AAEzB;;;;;;;;;;;;;;;;CAgBC,GACD,OAAO,MAAMC,+BAA+B,CAC1CC,UAEAN,OAAOO,GAAG,CAAC;QACT,MAAMC,qBAAqB,OAAOV;QAElC,OAAO;YACLW,MAAM,CACJC,gBAEAV,OAAOO,GAAG,CAAC;oBACT,MAAMI,MAAM,OAAOR,cAAcS,kBAAkB,CACjDJ,oBACAF,SACAF,kBACAM;oBAGF,MAAMG,WAAW,OAAOZ,+BACtBE,cAAcW,kBAAkB,CAAC;wBAAEC,QAAQ;wBAAOJ;oBAAI;oBAGxD,OAAO,OAAOZ,8BAA8Bc,SAASG,IAAI;gBAC3D,GAAGC,IAAI,CACLjB,OAAOkB,QAAQ,CAACC,CAAAA;wBACdA;2BAAAA,EAAAA,iBAAAA,MAAMC,OAAO,qBAAbD,cAAe,CAAC,SAAS,MAAK,MAC1BnB,OAAOqB,OAAO,CAACC,aACftB,OAAOuB,IAAI,CAACJ;;QAGxB;IACF,GAAG"}
@@ -0,0 +1,2 @@
1
+ export * from './build-transaction-status-reader.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapters/transaction-status/build-transaction-status-reader/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './build-transaction-status-reader.js';
2
+
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/adapters/transaction-status/build-transaction-status-reader/index.ts"],"sourcesContent":["export * from './build-transaction-status-reader.js';\n"],"names":[],"mappings":"AAAA,cAAc,uCAAuC"}
@@ -0,0 +1,5 @@
1
+ import { EntifixConnError } from '@entifix/core';
2
+ import { Effect } from 'effect';
3
+ import { HttpRequest, HttpResponse } from '../types.js';
4
+ export declare const performHttpRequestThroughFetch: <TResponseBody>(request: HttpRequest<unknown>) => Effect.Effect<HttpResponse<TResponseBody>, EntifixConnError, never>;
5
+ //# sourceMappingURL=fetch-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-client.d.ts","sourceRoot":"","sources":["../../../src/clients/fetch/fetch-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAExD,eAAO,MAAM,8BAA8B,GAAI,aAAa,EAC1D,SAAS,WAAW,CAAC,OAAO,CAAC,wEAmE3B,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ import { EntifixConnError } from '@entifix/core';
3
+ import { Effect } from 'effect';
4
+ export const performHttpRequestThroughFetch = (request)=>Effect.gen(function*() {
5
+ // Perform the HTTP request using the Fetch API
6
+ const response = yield* Effect.tryPromise({
7
+ try: ()=>fetch(request.url, {
8
+ method: request.method,
9
+ headers: request.headers,
10
+ body: request.body ? JSON.stringify(request.body) : undefined
11
+ }),
12
+ catch: (error)=>new EntifixConnError(`HTTP request to ${request.url} failed`, error, {
13
+ url: request.url,
14
+ method: request.method
15
+ })
16
+ });
17
+ // Check if the response is successful (status code 2xx)
18
+ if (!response.ok) {
19
+ // Services answer a failure with `{ error, code, detail }`. Carrying the
20
+ // `code` into `details` is what lets the browser render a translated
21
+ // message instead of the service's English `error` string. A body that is
22
+ // not JSON is not itself a failure — the status already is one.
23
+ const failure = yield* Effect.promise(()=>response.json().then((parsed)=>parsed, ()=>({})));
24
+ const code = failure['code'];
25
+ yield* Effect.fail(new EntifixConnError(`HTTP request failed with status ${response.status}: ${response.statusText}`, undefined, _extends({
26
+ status: response.status,
27
+ statusText: response.statusText,
28
+ url: request.url,
29
+ method: request.method
30
+ }, typeof code === 'string' ? {
31
+ code
32
+ } : {})));
33
+ }
34
+ // Parse the response body as JSON. If parse fails, fail with an EntifixExternalError with details about the failure.
35
+ const body = yield* Effect.tryPromise({
36
+ try: ()=>response.json(),
37
+ catch: (error)=>new EntifixConnError('Failed to parse response body as JSON', error, {
38
+ url: request.url,
39
+ method: request.method,
40
+ status: response.status,
41
+ statusText: response.statusText
42
+ })
43
+ });
44
+ // Return the HttpResponse object
45
+ const httpResponse = {
46
+ status: response.status,
47
+ headers: Object.fromEntries(response.headers.entries()),
48
+ body
49
+ };
50
+ return httpResponse;
51
+ });
52
+
53
+ //# sourceMappingURL=fetch-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/clients/fetch/fetch-client.ts"],"sourcesContent":["import { EntifixConnError } from '@entifix/core';\nimport { Effect } from 'effect';\n\nimport { HttpRequest, HttpResponse } from '../types.js';\n\nexport const performHttpRequestThroughFetch = <TResponseBody>(\n request: HttpRequest<unknown>,\n) =>\n Effect.gen(function* () {\n // Perform the HTTP request using the Fetch API\n const response = yield* Effect.tryPromise({\n try: () =>\n fetch(request.url, {\n method: request.method,\n headers: request.headers,\n body: request.body ? JSON.stringify(request.body) : undefined,\n }),\n catch: error =>\n new EntifixConnError(`HTTP request to ${request.url} failed`, error, {\n url: request.url,\n method: request.method,\n }),\n });\n\n // Check if the response is successful (status code 2xx)\n if (!response.ok) {\n // Services answer a failure with `{ error, code, detail }`. Carrying the\n // `code` into `details` is what lets the browser render a translated\n // message instead of the service's English `error` string. A body that is\n // not JSON is not itself a failure — the status already is one.\n const failure = yield* Effect.promise(() =>\n response.json().then(\n (parsed: unknown) => parsed as Record<string, unknown>,\n () => ({}) as Record<string, unknown>,\n ),\n );\n const code = failure['code'];\n\n yield* Effect.fail(\n new EntifixConnError(\n `HTTP request failed with status ${response.status}: ${response.statusText}`,\n undefined,\n {\n status: response.status,\n statusText: response.statusText,\n url: request.url,\n method: request.method,\n ...(typeof code === 'string' ? { code } : {}),\n },\n ),\n );\n }\n\n // Parse the response body as JSON. If parse fails, fail with an EntifixExternalError with details about the failure.\n const body = yield* Effect.tryPromise({\n try: () => response.json() as Promise<TResponseBody>,\n catch: error =>\n new EntifixConnError('Failed to parse response body as JSON', error, {\n url: request.url,\n method: request.method,\n status: response.status,\n statusText: response.statusText,\n }),\n });\n\n // Return the HttpResponse object\n const httpResponse: HttpResponse<TResponseBody> = {\n status: response.status,\n headers: Object.fromEntries(response.headers.entries()),\n body,\n };\n\n return httpResponse;\n });\n"],"names":["EntifixConnError","Effect","performHttpRequestThroughFetch","request","gen","response","tryPromise","try","fetch","url","method","headers","body","JSON","stringify","undefined","catch","error","ok","failure","promise","json","then","parsed","code","fail","status","statusText","httpResponse","Object","fromEntries","entries"],"mappings":";AAAA,SAASA,gBAAgB,QAAQ,gBAAgB;AACjD,SAASC,MAAM,QAAQ,SAAS;AAIhC,OAAO,MAAMC,iCAAiC,CAC5CC,UAEAF,OAAOG,GAAG,CAAC;QACT,+CAA+C;QAC/C,MAAMC,WAAW,OAAOJ,OAAOK,UAAU,CAAC;YACxCC,KAAK,IACHC,MAAML,QAAQM,GAAG,EAAE;oBACjBC,QAAQP,QAAQO,MAAM;oBACtBC,SAASR,QAAQQ,OAAO;oBACxBC,MAAMT,QAAQS,IAAI,GAAGC,KAAKC,SAAS,CAACX,QAAQS,IAAI,IAAIG;gBACtD;YACFC,OAAOC,CAAAA,QACL,IAAIjB,iBAAiB,CAAC,gBAAgB,EAAEG,QAAQM,GAAG,CAAC,OAAO,CAAC,EAAEQ,OAAO;oBACnER,KAAKN,QAAQM,GAAG;oBAChBC,QAAQP,QAAQO,MAAM;gBACxB;QACJ;QAEA,wDAAwD;QACxD,IAAI,CAACL,SAASa,EAAE,EAAE;YAChB,yEAAyE;YACzE,qEAAqE;YACrE,0EAA0E;YAC1E,gEAAgE;YAChE,MAAMC,UAAU,OAAOlB,OAAOmB,OAAO,CAAC,IACpCf,SAASgB,IAAI,GAAGC,IAAI,CAClB,CAACC,SAAoBA,QACrB,IAAO,CAAA,CAAC,CAAA;YAGZ,MAAMC,OAAOL,OAAO,CAAC,OAAO;YAE5B,OAAOlB,OAAOwB,IAAI,CAChB,IAAIzB,iBACF,CAAC,gCAAgC,EAAEK,SAASqB,MAAM,CAAC,EAAE,EAAErB,SAASsB,UAAU,EAAE,EAC5EZ,WACA;gBACEW,QAAQrB,SAASqB,MAAM;gBACvBC,YAAYtB,SAASsB,UAAU;gBAC/BlB,KAAKN,QAAQM,GAAG;gBAChBC,QAAQP,QAAQO,MAAM;eAClB,OAAOc,SAAS,WAAW;gBAAEA;YAAK,IAAI,CAAC;QAInD;QAEA,qHAAqH;QACrH,MAAMZ,OAAO,OAAOX,OAAOK,UAAU,CAAC;YACpCC,KAAK,IAAMF,SAASgB,IAAI;YACxBL,OAAOC,CAAAA,QACL,IAAIjB,iBAAiB,yCAAyCiB,OAAO;oBACnER,KAAKN,QAAQM,GAAG;oBAChBC,QAAQP,QAAQO,MAAM;oBACtBgB,QAAQrB,SAASqB,MAAM;oBACvBC,YAAYtB,SAASsB,UAAU;gBACjC;QACJ;QAEA,iCAAiC;QACjC,MAAMC,eAA4C;YAChDF,QAAQrB,SAASqB,MAAM;YACvBf,SAASkB,OAAOC,WAAW,CAACzB,SAASM,OAAO,CAACoB,OAAO;YACpDnB;QACF;QAEA,OAAOgB;IACT,GAAG"}
@@ -0,0 +1,2 @@
1
+ export * from './fetch-client.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/clients/fetch/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './fetch-client.js';
2
+
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/clients/fetch/index.ts"],"sourcesContent":["export * from './fetch-client.js';\n"],"names":[],"mappings":"AAAA,cAAc,oBAAoB"}
@@ -0,0 +1,14 @@
1
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
2
+ export type HttpHeaders = Record<string, string>;
3
+ export interface HttpRequest<TBody = never> {
4
+ method: HttpMethod;
5
+ url: string;
6
+ headers?: HttpHeaders;
7
+ body?: TBody;
8
+ }
9
+ export interface HttpResponse<TBody> {
10
+ status: number;
11
+ headers: HttpHeaders;
12
+ body: TBody;
13
+ }
14
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/clients/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE3D,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEjD,MAAM,WAAW,WAAW,CAAC,KAAK,GAAG,KAAK;IACxC,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,IAAI,CAAC,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,YAAY,CAAC,KAAK;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,KAAK,CAAC;CACb"}
@@ -0,0 +1,3 @@
1
+ export { };
2
+
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/clients/types.ts"],"sourcesContent":["export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';\n\nexport type HttpHeaders = Record<string, string>;\n\nexport interface HttpRequest<TBody = never> {\n method: HttpMethod;\n url: string;\n headers?: HttpHeaders;\n body?: TBody;\n}\n\nexport interface HttpResponse<TBody> {\n status: number;\n headers: HttpHeaders;\n body: TBody;\n}\n"],"names":[],"mappings":"AAWA,WAIC"}
@@ -0,0 +1,28 @@
1
+ import { ConfigurationClient, ConfigurationClientGroup } from '@entifix/core';
2
+ export interface ConfigurationClientRestClientOptions {
3
+ /** Endpoint returning this service's `ConfigurationPlain`. */
4
+ url?: string;
5
+ /**
6
+ * Headers to send with the lookup.
7
+ *
8
+ * Empty for the browser, which reads its own app's same-origin `/api/config`
9
+ * and needs nothing. A **server** component reads config-service directly —
10
+ * there is no origin to proxy through and no browser to hide an address from
11
+ * — and that endpoint is gated on the shared fleet token, so the caller has
12
+ * to carry it. The header itself stays out of this package: the token is a
13
+ * Next server concern and lives in `@entifix/next-shell`.
14
+ */
15
+ headers?: Readonly<Record<string, string>>;
16
+ }
17
+ /**
18
+ * {@link ConfigurationClient} that sources its `ConfigurationPlain` over HTTP
19
+ * (by default the same-origin `/api/config` route, which proxies
20
+ * marketplace-config-api). The fetched configuration is memoized so it is
21
+ * requested at most once per client instance.
22
+ */
23
+ export declare class ConfigurationClientRestClient implements ConfigurationClient {
24
+ #private;
25
+ constructor(options?: ConfigurationClientRestClientOptions);
26
+ in(group: string): ConfigurationClientGroup;
27
+ }
28
+ //# sourceMappingURL=configuration-client-rest-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configuration-client-rest-client.d.ts","sourceRoot":"","sources":["../../src/configuration-client/configuration-client-rest-client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EAKzB,MAAM,eAAe,CAAC;AAGvB,MAAM,WAAW,oCAAoC;IACnD,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC5C;AAuED;;;;;GAKG;AACH,qBAAa,6BAA8B,YAAW,mBAAmB;;gBAG3D,OAAO,CAAC,EAAE,oCAAoC;IAoB1D,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,wBAAwB;CAG5C"}
@@ -0,0 +1,94 @@
1
+ import { _ as _class_private_field_loose_base } from "@swc/helpers/_/_class_private_field_loose_base";
2
+ import { _ as _class_private_field_loose_key } from "@swc/helpers/_/_class_private_field_loose_key";
3
+ import { ConfigurationClientInMemory, EntifixBuildError } from '@entifix/core';
4
+ import { Effect } from 'effect';
5
+ const DEFAULT_CONFIG_URL = '/api/config';
6
+ var _pending = /*#__PURE__*/ _class_private_field_loose_key("_pending");
7
+ /**
8
+ * {@link ConfigurationClientGroup} view over an HTTP-sourced
9
+ * {@link ConfigurationPlain}. Resolution is delegated to an in-memory store
10
+ * once the plain configuration has been fetched.
11
+ */ let ConfigurationClientGroupRestClient = class ConfigurationClientGroupRestClient {
12
+ getString(key, extractMode) {
13
+ return this.loadPlain.pipe(Effect.flatMap((plain)=>new ConfigurationClientInMemory(plain).in(this.group).getString(key, extractMode)));
14
+ }
15
+ getNumber() {
16
+ return _class_private_field_loose_base(this, _pending)[_pending]();
17
+ }
18
+ getDate() {
19
+ return _class_private_field_loose_base(this, _pending)[_pending]();
20
+ }
21
+ getArrayNumber() {
22
+ return _class_private_field_loose_base(this, _pending)[_pending]();
23
+ }
24
+ getArrayString() {
25
+ return _class_private_field_loose_base(this, _pending)[_pending]();
26
+ }
27
+ getArrayDate() {
28
+ return _class_private_field_loose_base(this, _pending)[_pending]();
29
+ }
30
+ getOptionalNumber() {
31
+ return _class_private_field_loose_base(this, _pending)[_pending]();
32
+ }
33
+ getOptionalString() {
34
+ return _class_private_field_loose_base(this, _pending)[_pending]();
35
+ }
36
+ getOptionalDate() {
37
+ return _class_private_field_loose_base(this, _pending)[_pending]();
38
+ }
39
+ getOptionalArrayNumber() {
40
+ return _class_private_field_loose_base(this, _pending)[_pending]();
41
+ }
42
+ getOptionalArrayString() {
43
+ return _class_private_field_loose_base(this, _pending)[_pending]();
44
+ }
45
+ getOptionalArrayDate() {
46
+ return _class_private_field_loose_base(this, _pending)[_pending]();
47
+ }
48
+ constructor(loadPlain, group){
49
+ Object.defineProperty(this, _pending, {
50
+ value: pending
51
+ });
52
+ this.loadPlain = loadPlain;
53
+ this.group = group;
54
+ }
55
+ };
56
+ function pending() {
57
+ return Effect.die(new Error('ConfigurationClientGroupRestClient getter not implemented yet'));
58
+ }
59
+ var _loadPlain = /*#__PURE__*/ _class_private_field_loose_key("_loadPlain");
60
+ /**
61
+ * {@link ConfigurationClient} that sources its `ConfigurationPlain` over HTTP
62
+ * (by default the same-origin `/api/config` route, which proxies
63
+ * marketplace-config-api). The fetched configuration is memoized so it is
64
+ * requested at most once per client instance.
65
+ */ export class ConfigurationClientRestClient {
66
+ in(group) {
67
+ return new ConfigurationClientGroupRestClient(_class_private_field_loose_base(this, _loadPlain)[_loadPlain], group);
68
+ }
69
+ constructor(options){
70
+ var _ref;
71
+ Object.defineProperty(this, _loadPlain, {
72
+ writable: true,
73
+ value: void 0
74
+ });
75
+ const url = (_ref = options == null ? void 0 : options.url) != null ? _ref : DEFAULT_CONFIG_URL;
76
+ const headers = options == null ? void 0 : options.headers;
77
+ let cache;
78
+ _class_private_field_loose_base(this, _loadPlain)[_loadPlain] = Effect.tryPromise({
79
+ try: ()=>cache != null ? cache : cache = fetch(url, {
80
+ headers
81
+ }).then((response)=>{
82
+ if (!response.ok) {
83
+ throw new Error(`Configuration request to ${url} failed with status ${response.status}`);
84
+ }
85
+ return response.json();
86
+ }),
87
+ catch: (error)=>new EntifixBuildError('Failed to load configuration', error, {
88
+ url
89
+ })
90
+ });
91
+ }
92
+ }
93
+
94
+ //# sourceMappingURL=configuration-client-rest-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/configuration-client/configuration-client-rest-client.ts"],"sourcesContent":["import {\n ConfigurationClient,\n ConfigurationClientGroup,\n ConfigurationClientInMemory,\n ConfigurationExtractMode,\n ConfigurationPlain,\n EntifixBuildError,\n} from '@entifix/core';\nimport { Effect } from 'effect';\n\nexport interface ConfigurationClientRestClientOptions {\n /** Endpoint returning this service's `ConfigurationPlain`. */\n url?: string;\n /**\n * Headers to send with the lookup.\n *\n * Empty for the browser, which reads its own app's same-origin `/api/config`\n * and needs nothing. A **server** component reads config-service directly —\n * there is no origin to proxy through and no browser to hide an address from\n * — and that endpoint is gated on the shared fleet token, so the caller has\n * to carry it. The header itself stays out of this package: the token is a\n * Next server concern and lives in `@entifix/next-shell`.\n */\n headers?: Readonly<Record<string, string>>;\n}\n\nconst DEFAULT_CONFIG_URL = '/api/config';\n\n/**\n * {@link ConfigurationClientGroup} view over an HTTP-sourced\n * {@link ConfigurationPlain}. Resolution is delegated to an in-memory store\n * once the plain configuration has been fetched.\n */\nclass ConfigurationClientGroupRestClient implements ConfigurationClientGroup {\n constructor(\n private readonly loadPlain: Effect.Effect<\n ConfigurationPlain,\n EntifixBuildError\n >,\n private readonly group: string,\n ) {}\n\n #pending() {\n return Effect.die(\n new Error(\n 'ConfigurationClientGroupRestClient getter not implemented yet',\n ),\n );\n }\n\n getString(key: string, extractMode?: ConfigurationExtractMode) {\n return this.loadPlain.pipe(\n Effect.flatMap(plain =>\n new ConfigurationClientInMemory(plain)\n .in(this.group)\n .getString(key, extractMode),\n ),\n );\n }\n\n getNumber() {\n return this.#pending();\n }\n getDate() {\n return this.#pending();\n }\n getArrayNumber() {\n return this.#pending();\n }\n getArrayString() {\n return this.#pending();\n }\n getArrayDate() {\n return this.#pending();\n }\n getOptionalNumber() {\n return this.#pending();\n }\n getOptionalString() {\n return this.#pending();\n }\n getOptionalDate() {\n return this.#pending();\n }\n getOptionalArrayNumber() {\n return this.#pending();\n }\n getOptionalArrayString() {\n return this.#pending();\n }\n getOptionalArrayDate() {\n return this.#pending();\n }\n}\n\n/**\n * {@link ConfigurationClient} that sources its `ConfigurationPlain` over HTTP\n * (by default the same-origin `/api/config` route, which proxies\n * marketplace-config-api). The fetched configuration is memoized so it is\n * requested at most once per client instance.\n */\nexport class ConfigurationClientRestClient implements ConfigurationClient {\n #loadPlain: Effect.Effect<ConfigurationPlain, EntifixBuildError>;\n\n constructor(options?: ConfigurationClientRestClientOptions) {\n const url = options?.url ?? DEFAULT_CONFIG_URL;\n const headers = options?.headers;\n let cache: Promise<ConfigurationPlain> | undefined;\n\n this.#loadPlain = Effect.tryPromise({\n try: () =>\n (cache ??= fetch(url, { headers }).then(response => {\n if (!response.ok) {\n throw new Error(\n `Configuration request to ${url} failed with status ${response.status}`,\n );\n }\n return response.json() as Promise<ConfigurationPlain>;\n })),\n catch: error =>\n new EntifixBuildError('Failed to load configuration', error, { url }),\n });\n }\n\n in(group: string): ConfigurationClientGroup {\n return new ConfigurationClientGroupRestClient(this.#loadPlain, group);\n }\n}\n"],"names":["ConfigurationClientInMemory","EntifixBuildError","Effect","DEFAULT_CONFIG_URL","ConfigurationClientGroupRestClient","getString","key","extractMode","loadPlain","pipe","flatMap","plain","in","group","getNumber","getDate","getArrayNumber","getArrayString","getArrayDate","getOptionalNumber","getOptionalString","getOptionalDate","getOptionalArrayNumber","getOptionalArrayString","getOptionalArrayDate","die","Error","ConfigurationClientRestClient","options","url","headers","cache","tryPromise","try","fetch","then","response","ok","status","json","catch","error"],"mappings":";;AAAA,SAGEA,2BAA2B,EAG3BC,iBAAiB,QACZ,gBAAgB;AACvB,SAASC,MAAM,QAAQ,SAAS;AAkBhC,MAAMC,qBAAqB;IAgBzB;AAdF;;;;CAIC,GACD,IAAA,AAAMC,qCAAN,MAAMA;IAiBJC,UAAUC,GAAW,EAAEC,WAAsC,EAAE;QAC7D,OAAO,IAAI,CAACC,SAAS,CAACC,IAAI,CACxBP,OAAOQ,OAAO,CAACC,CAAAA,QACb,IAAIX,4BAA4BW,OAC7BC,EAAE,CAAC,IAAI,CAACC,KAAK,EACbR,SAAS,CAACC,KAAKC;IAGxB;IAEAO,YAAY;QACV,OAAO,gCAAA,IAAI,EAAC,UAAA;IACd;IACAC,UAAU;QACR,OAAO,gCAAA,IAAI,EAAC,UAAA;IACd;IACAC,iBAAiB;QACf,OAAO,gCAAA,IAAI,EAAC,UAAA;IACd;IACAC,iBAAiB;QACf,OAAO,gCAAA,IAAI,EAAC,UAAA;IACd;IACAC,eAAe;QACb,OAAO,gCAAA,IAAI,EAAC,UAAA;IACd;IACAC,oBAAoB;QAClB,OAAO,gCAAA,IAAI,EAAC,UAAA;IACd;IACAC,oBAAoB;QAClB,OAAO,gCAAA,IAAI,EAAC,UAAA;IACd;IACAC,kBAAkB;QAChB,OAAO,gCAAA,IAAI,EAAC,UAAA;IACd;IACAC,yBAAyB;QACvB,OAAO,gCAAA,IAAI,EAAC,UAAA;IACd;IACAC,yBAAyB;QACvB,OAAO,gCAAA,IAAI,EAAC,UAAA;IACd;IACAC,uBAAuB;QACrB,OAAO,gCAAA,IAAI,EAAC,UAAA;IACd;IA1DA,YACE,AAAiBhB,SAGhB,EACD,AAAiBK,KAAa,CAC9B;QAEF,4BAAA;mBAAA;;aAPmBL,YAAAA;aAIAK,QAAAA;IAChB;AAqDL;AAnDE,SAAA;IACE,OAAOX,OAAOuB,GAAG,CACf,IAAIC,MACF;AAGN;IAsDA;AAPF;;;;;CAKC,GACD,OAAO,MAAMC;IAuBXf,GAAGC,KAAa,EAA4B;QAC1C,OAAO,IAAIT,mCAAmC,gCAAA,IAAI,EAAC,YAAA,aAAYS;IACjE;IAtBA,YAAYe,OAA8C,CAAE;;QAF5D,4BAAA;;mBAAA,KAAA;;QAGE,MAAMC,cAAMD,2BAAAA,QAASC,GAAG,mBAAI1B;QAC5B,MAAM2B,UAAUF,2BAAAA,QAASE,OAAO;QAChC,IAAIC;QAEJ,gCAAA,IAAI,EAAC,YAAA,cAAa7B,OAAO8B,UAAU,CAAC;YAClCC,KAAK,IACFF,gBAAAA,QAAAA,QAAUG,MAAML,KAAK;oBAAEC;gBAAQ,GAAGK,IAAI,CAACC,CAAAA;oBACtC,IAAI,CAACA,SAASC,EAAE,EAAE;wBAChB,MAAM,IAAIX,MACR,CAAC,yBAAyB,EAAEG,IAAI,oBAAoB,EAAEO,SAASE,MAAM,EAAE;oBAE3E;oBACA,OAAOF,SAASG,IAAI;gBACtB;YACFC,OAAOC,CAAAA,QACL,IAAIxC,kBAAkB,gCAAgCwC,OAAO;oBAAEZ;gBAAI;QACvE;IACF;AAKF"}
@@ -0,0 +1,2 @@
1
+ export * from './configuration-client-rest-client.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/configuration-client/index.ts"],"names":[],"mappings":"AAAA,cAAc,uCAAuC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './configuration-client-rest-client.js';
2
+
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/configuration-client/index.ts"],"sourcesContent":["export * from './configuration-client-rest-client.js';\n"],"names":[],"mappings":"AAAA,cAAc,wCAAwC"}
@@ -0,0 +1,11 @@
1
+ export * from './adapters/entity-metadata/make-entity-metadata-source/index.js';
2
+ export * from './adapters/entity-rest/build-entity-rest-adapter-delete/index.js';
3
+ export * from './adapters/entity-rest/build-entity-rest-adapter-get/index.js';
4
+ export * from './adapters/entity-rest/build-entity-rest-adapter-load/index.js';
5
+ export * from './adapters/entity-rest/build-entity-rest-adapter-save/index.js';
6
+ export * from './adapters/entity-rest/types.js';
7
+ export * from './adapters/transaction-status/build-transaction-status-reader/index.js';
8
+ export * from './clients/fetch/index.js';
9
+ export * from './clients/types.js';
10
+ export * from './configuration-client/index.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iEAAiE,CAAC;AAChF,cAAc,kEAAkE,CAAC;AACjF,cAAc,+DAA+D,CAAC;AAC9E,cAAc,gEAAgE,CAAC;AAC/E,cAAc,gEAAgE,CAAC;AAC/E,cAAc,iCAAiC,CAAC;AAChD,cAAc,wEAAwE,CAAC;AACvF,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iCAAiC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ export * from './adapters/entity-metadata/make-entity-metadata-source/index.js';
2
+ export * from './adapters/entity-rest/build-entity-rest-adapter-delete/index.js';
3
+ export * from './adapters/entity-rest/build-entity-rest-adapter-get/index.js';
4
+ export * from './adapters/entity-rest/build-entity-rest-adapter-load/index.js';
5
+ export * from './adapters/entity-rest/build-entity-rest-adapter-save/index.js';
6
+ export * from './adapters/entity-rest/types.js';
7
+ export * from './adapters/transaction-status/build-transaction-status-reader/index.js';
8
+ export * from './clients/fetch/index.js';
9
+ export * from './clients/types.js';
10
+ export * from './configuration-client/index.js';
11
+
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './adapters/entity-metadata/make-entity-metadata-source/index.js';\nexport * from './adapters/entity-rest/build-entity-rest-adapter-delete/index.js';\nexport * from './adapters/entity-rest/build-entity-rest-adapter-get/index.js';\nexport * from './adapters/entity-rest/build-entity-rest-adapter-load/index.js';\nexport * from './adapters/entity-rest/build-entity-rest-adapter-save/index.js';\nexport * from './adapters/entity-rest/types.js';\nexport * from './adapters/transaction-status/build-transaction-status-reader/index.js';\nexport * from './clients/fetch/index.js';\nexport * from './clients/types.js';\nexport * from './configuration-client/index.js';\n"],"names":[],"mappings":"AAAA,cAAc,kEAAkE;AAChF,cAAc,mEAAmE;AACjF,cAAc,gEAAgE;AAC9E,cAAc,iEAAiE;AAC/E,cAAc,iEAAiE;AAC/E,cAAc,kCAAkC;AAChD,cAAc,yEAAyE;AACvF,cAAc,2BAA2B;AACzC,cAAc,qBAAqB;AACnC,cAAc,kCAAkC"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@entifix/rest",
3
+ "version": "0.1.0-0",
4
+ "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/r10c-technologies/entifix.git",
8
+ "directory": "packages/ts/rest-client"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "type": "module",
14
+ "main": "./dist/index.js",
15
+ "module": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ "./package.json": "./package.json",
19
+ ".": {
20
+ "@entifix/source": "./src/index.ts",
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js",
23
+ "default": "./dist/index.js"
24
+ }
25
+ },
26
+ "files": [
27
+ "dist",
28
+ "!**/*.tsbuildinfo",
29
+ "LICENSE"
30
+ ],
31
+ "nx": {
32
+ "tags": [
33
+ "layer:entifix",
34
+ "scope:shared",
35
+ "entifix:client",
36
+ "tier:2"
37
+ ],
38
+ "sourceRoot": "packages/ts/rest-client/src",
39
+ "targets": {
40
+ "build": {
41
+ "executor": "@nx/js:swc",
42
+ "outputs": [
43
+ "{options.outputPath}"
44
+ ],
45
+ "options": {
46
+ "outputPath": "packages/ts/rest-client/dist",
47
+ "main": "packages/ts/rest-client/src/index.ts",
48
+ "tsConfig": "packages/ts/rest-client/tsconfig.lib.json",
49
+ "skipTypeCheck": true,
50
+ "stripLeadingPaths": true
51
+ }
52
+ }
53
+ }
54
+ },
55
+ "dependencies": {
56
+ "@swc/helpers": "0.5.23",
57
+ "@entifix/business": "0.1.0-0",
58
+ "@entifix/core": "0.1.0-0",
59
+ "@entifix/transactions": "0.1.0-0"
60
+ },
61
+ "devDependencies": {
62
+ "effect": "3.22.1",
63
+ "@entifix/testing-unit": "0.1.0-0"
64
+ },
65
+ "peerDependencies": {
66
+ "effect": ">=3.22 <4"
67
+ }
68
+ }