@plyaz/core 1.7.0 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/domain/base/BaseDomainService.d.ts.map +1 -1
- package/dist/domain/base/BaseFrontendDomainService.d.ts +28 -0
- package/dist/domain/base/BaseFrontendDomainService.d.ts.map +1 -1
- package/dist/domain/example/FrontendExampleDomainService.d.ts.map +1 -1
- package/dist/domain/example/mappers/ExampleMapper.d.ts.map +1 -1
- package/dist/entry-backend.js +143 -37
- package/dist/entry-backend.js.map +1 -1
- package/dist/entry-backend.mjs +143 -37
- package/dist/entry-backend.mjs.map +1 -1
- package/dist/entry-frontend-browser.js +142 -37
- package/dist/entry-frontend-browser.js.map +1 -1
- package/dist/entry-frontend-browser.mjs +142 -37
- package/dist/entry-frontend-browser.mjs.map +1 -1
- package/dist/entry-frontend.js +142 -37
- package/dist/entry-frontend.js.map +1 -1
- package/dist/entry-frontend.mjs +142 -37
- package/dist/entry-frontend.mjs.map +1 -1
- package/dist/index.js +540 -437
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1711 -1608
- package/dist/index.mjs.map +1 -1
- package/dist/init/CoreInitializer.d.ts +5 -0
- package/dist/init/CoreInitializer.d.ts.map +1 -1
- package/dist/init/nestjs/index.js +7 -0
- package/dist/init/nestjs/index.js.map +1 -1
- package/dist/init/nestjs/index.mjs +7 -0
- package/dist/init/nestjs/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -7,10 +7,10 @@ require('@plyaz/types/globals');
|
|
|
7
7
|
var logger$1 = require('@plyaz/logger');
|
|
8
8
|
var errors$1 = require('@plyaz/types/errors');
|
|
9
9
|
var frontend = require('@plyaz/api/frontend');
|
|
10
|
-
var store = require('@plyaz/store');
|
|
11
10
|
var events = require('events');
|
|
12
11
|
var observability = require('@plyaz/types/observability');
|
|
13
12
|
var middleware = require('@plyaz/errors/middleware');
|
|
13
|
+
var store = require('@plyaz/store');
|
|
14
14
|
var core = require('@plyaz/types/core');
|
|
15
15
|
var fs = require('fs');
|
|
16
16
|
var path = require('path');
|
|
@@ -32735,404 +32735,6 @@ var require_cjs = __commonJS({
|
|
|
32735
32735
|
}, "get") });
|
|
32736
32736
|
}
|
|
32737
32737
|
});
|
|
32738
|
-
var BaseDomainService = class {
|
|
32739
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
32740
|
-
// Constructor
|
|
32741
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
32742
|
-
/**
|
|
32743
|
-
* Create a new domain service instance
|
|
32744
|
-
*
|
|
32745
|
-
* @param config - Base service configuration (passed via super({...}))
|
|
32746
|
-
*/
|
|
32747
|
-
// eslint-disable-next-line complexity
|
|
32748
|
-
constructor(config) {
|
|
32749
|
-
/** Initialization state */
|
|
32750
|
-
this._initialized = false;
|
|
32751
|
-
// API Client (optional)
|
|
32752
|
-
this._apiClient = null;
|
|
32753
|
-
this._clientInitPromise = null;
|
|
32754
|
-
/**
|
|
32755
|
-
* Cache prefix for namespacing cache keys (e.g., 'example', 'user', 'product').
|
|
32756
|
-
* Subclasses can override by defining as a property.
|
|
32757
|
-
* If not overridden, defaults to serviceName.toLowerCase().
|
|
32758
|
-
*
|
|
32759
|
-
* @example
|
|
32760
|
-
* ```typescript
|
|
32761
|
-
* protected cachePrefix = 'my-service'; // Override default
|
|
32762
|
-
* ```
|
|
32763
|
-
*/
|
|
32764
|
-
this.cachePrefix = "";
|
|
32765
|
-
// Mapper and Validator instances (lazy)
|
|
32766
|
-
this._mapperInstance = null;
|
|
32767
|
-
this._validatorInstance = null;
|
|
32768
|
-
this.serviceName = config.serviceName;
|
|
32769
|
-
this.supportedRuntimes = config.supportedRuntimes;
|
|
32770
|
-
this.config = config.serviceConfig;
|
|
32771
|
-
this._setAsDefaultClient = config.setAsDefaultClient ?? false;
|
|
32772
|
-
this.logger = new logger$1.PackageLogger({
|
|
32773
|
-
packageName: "core",
|
|
32774
|
-
service: this.serviceName
|
|
32775
|
-
});
|
|
32776
|
-
this._apiClientConfig = config.apiClientConfig;
|
|
32777
|
-
this.cacheManager = config.injected?.cache;
|
|
32778
|
-
this.dbService = config.injected?.db;
|
|
32779
|
-
this.apiService = config.injected?.api;
|
|
32780
|
-
this.observabilityService = config.serviceConfig.observabilityOverride ?? config.injected?.observability;
|
|
32781
|
-
if (!this.cachePrefix) {
|
|
32782
|
-
this.cachePrefix = this.serviceName.toLowerCase();
|
|
32783
|
-
}
|
|
32784
|
-
this._MapperClass = config.mapperClass;
|
|
32785
|
-
this._ValidatorClass = config.validatorClass;
|
|
32786
|
-
if (this._apiClientConfig) {
|
|
32787
|
-
this.initializeApiClient();
|
|
32788
|
-
}
|
|
32789
|
-
this.logger.debug(`${this.serviceName} created`, {
|
|
32790
|
-
supportedRuntimes: this.supportedRuntimes,
|
|
32791
|
-
hasApiClient: !!this._apiClientConfig,
|
|
32792
|
-
injected: {
|
|
32793
|
-
cache: !!this.cacheManager,
|
|
32794
|
-
db: !!this.dbService,
|
|
32795
|
-
api: !!this.apiService,
|
|
32796
|
-
observability: !!this.observabilityService
|
|
32797
|
-
},
|
|
32798
|
-
cachePrefix: this.cachePrefix,
|
|
32799
|
-
hasMapper: !!this._MapperClass,
|
|
32800
|
-
hasValidator: !!this._ValidatorClass
|
|
32801
|
-
});
|
|
32802
|
-
}
|
|
32803
|
-
static {
|
|
32804
|
-
__name(this, "BaseDomainService");
|
|
32805
|
-
}
|
|
32806
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
32807
|
-
// Getters
|
|
32808
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
32809
|
-
/**
|
|
32810
|
-
* Check if the service is enabled
|
|
32811
|
-
* Service is enabled by default unless explicitly disabled
|
|
32812
|
-
*/
|
|
32813
|
-
get isServiceEnabled() {
|
|
32814
|
-
return this.config?.enabled !== false;
|
|
32815
|
-
}
|
|
32816
|
-
/**
|
|
32817
|
-
* Check if the service is initialized (API client ready)
|
|
32818
|
-
*/
|
|
32819
|
-
get isInitialized() {
|
|
32820
|
-
return this._initialized;
|
|
32821
|
-
}
|
|
32822
|
-
/**
|
|
32823
|
-
* Check if mapper is available
|
|
32824
|
-
*/
|
|
32825
|
-
get hasMapper() {
|
|
32826
|
-
return !!this._MapperClass;
|
|
32827
|
-
}
|
|
32828
|
-
/**
|
|
32829
|
-
* Check if validator is available
|
|
32830
|
-
*/
|
|
32831
|
-
get hasValidator() {
|
|
32832
|
-
return !!this._ValidatorClass;
|
|
32833
|
-
}
|
|
32834
|
-
/**
|
|
32835
|
-
* Get the mapper instance (lazy initialization)
|
|
32836
|
-
* @throws CorePackageError if MapperClass was not provided
|
|
32837
|
-
*/
|
|
32838
|
-
get mapper() {
|
|
32839
|
-
if (!this._mapperInstance && this._MapperClass) {
|
|
32840
|
-
this._mapperInstance = new this._MapperClass();
|
|
32841
|
-
}
|
|
32842
|
-
if (!this._mapperInstance) {
|
|
32843
|
-
throw new errors.CorePackageError(
|
|
32844
|
-
`${this.serviceName} does not have a Mapper configured`,
|
|
32845
|
-
errors$1.ERROR_CODES.FEATURE_NOT_SUPPORTED
|
|
32846
|
-
);
|
|
32847
|
-
}
|
|
32848
|
-
return this._mapperInstance;
|
|
32849
|
-
}
|
|
32850
|
-
/**
|
|
32851
|
-
* Set the mapper instance
|
|
32852
|
-
* Allows subclasses to override mapper initialization
|
|
32853
|
-
*/
|
|
32854
|
-
set mapper(value) {
|
|
32855
|
-
this._mapperInstance = value;
|
|
32856
|
-
}
|
|
32857
|
-
/**
|
|
32858
|
-
* Get the validator instance (lazy initialization)
|
|
32859
|
-
* @throws CorePackageError if ValidatorClass was not provided
|
|
32860
|
-
*/
|
|
32861
|
-
get validator() {
|
|
32862
|
-
if (!this._validatorInstance && this._ValidatorClass) {
|
|
32863
|
-
this._validatorInstance = new this._ValidatorClass();
|
|
32864
|
-
}
|
|
32865
|
-
if (!this._validatorInstance) {
|
|
32866
|
-
throw new errors.CorePackageError(
|
|
32867
|
-
`${this.serviceName} does not have a Validator configured`,
|
|
32868
|
-
errors$1.ERROR_CODES.FEATURE_NOT_SUPPORTED
|
|
32869
|
-
);
|
|
32870
|
-
}
|
|
32871
|
-
return this._validatorInstance;
|
|
32872
|
-
}
|
|
32873
|
-
/**
|
|
32874
|
-
* Set the validator instance
|
|
32875
|
-
* Allows subclasses to override validator initialization
|
|
32876
|
-
*/
|
|
32877
|
-
set validator(value) {
|
|
32878
|
-
this._validatorInstance = value;
|
|
32879
|
-
}
|
|
32880
|
-
/**
|
|
32881
|
-
* Get the API client (after initialization)
|
|
32882
|
-
* @throws CorePackageError if API client was not configured or not initialized
|
|
32883
|
-
*/
|
|
32884
|
-
get apiClient() {
|
|
32885
|
-
if (!this._apiClient) {
|
|
32886
|
-
throw new errors.CorePackageError(
|
|
32887
|
-
`${this.serviceName} API client not initialized. Call ensureApiClientInitialized() first.`,
|
|
32888
|
-
errors$1.ERROR_CODES.CLIENT_INITIALIZATION_FAILED
|
|
32889
|
-
);
|
|
32890
|
-
}
|
|
32891
|
-
return this._apiClient;
|
|
32892
|
-
}
|
|
32893
|
-
/**
|
|
32894
|
-
* Get the observability adapter (if injected)
|
|
32895
|
-
* Returns undefined if observability is not enabled
|
|
32896
|
-
*/
|
|
32897
|
-
get observability() {
|
|
32898
|
-
return this.observabilityService;
|
|
32899
|
-
}
|
|
32900
|
-
/**
|
|
32901
|
-
* Check if observability is available
|
|
32902
|
-
*/
|
|
32903
|
-
get hasObservability() {
|
|
32904
|
-
return !!this.observabilityService;
|
|
32905
|
-
}
|
|
32906
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
32907
|
-
// API Client Initialization
|
|
32908
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
32909
|
-
/**
|
|
32910
|
-
* Initialize API client asynchronously
|
|
32911
|
-
* Called from constructor if apiClientConfig is provided
|
|
32912
|
-
*/
|
|
32913
|
-
initializeApiClient() {
|
|
32914
|
-
if (this._clientInitPromise || !this._apiClientConfig) {
|
|
32915
|
-
return;
|
|
32916
|
-
}
|
|
32917
|
-
this._clientInitPromise = (async () => {
|
|
32918
|
-
try {
|
|
32919
|
-
this._apiClient = await frontend.createApiClient(this._apiClientConfig);
|
|
32920
|
-
if (this._setAsDefaultClient) {
|
|
32921
|
-
frontend.setDefaultApiClient(this._apiClient);
|
|
32922
|
-
}
|
|
32923
|
-
this._initialized = true;
|
|
32924
|
-
this.logger.debug("API client initialized", {
|
|
32925
|
-
service: this.serviceName,
|
|
32926
|
-
baseURL: this._apiClientConfig.baseURL
|
|
32927
|
-
});
|
|
32928
|
-
} catch (error) {
|
|
32929
|
-
this.logger.error("Failed to initialize API client", {
|
|
32930
|
-
service: this.serviceName,
|
|
32931
|
-
error: error instanceof Error ? error.message : String(error)
|
|
32932
|
-
});
|
|
32933
|
-
throw error;
|
|
32934
|
-
}
|
|
32935
|
-
})();
|
|
32936
|
-
}
|
|
32937
|
-
/**
|
|
32938
|
-
* Ensure API client is initialized before use.
|
|
32939
|
-
* Call this from methods that need the API client.
|
|
32940
|
-
* Also called by ServiceRegistry.create() for services with async initialization.
|
|
32941
|
-
*/
|
|
32942
|
-
async ensureApiClientInitialized() {
|
|
32943
|
-
if (this._clientInitPromise) {
|
|
32944
|
-
await this._clientInitPromise;
|
|
32945
|
-
}
|
|
32946
|
-
if (this._apiClientConfig && !this._apiClient) {
|
|
32947
|
-
throw new errors.CorePackageError(
|
|
32948
|
-
`${this.serviceName} API client not initialized`,
|
|
32949
|
-
errors$1.ERROR_CODES.CLIENT_INITIALIZATION_FAILED
|
|
32950
|
-
);
|
|
32951
|
-
}
|
|
32952
|
-
}
|
|
32953
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
32954
|
-
// Configuration Management
|
|
32955
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
32956
|
-
/**
|
|
32957
|
-
* Get current configuration (immutable copy)
|
|
32958
|
-
*/
|
|
32959
|
-
getConfig() {
|
|
32960
|
-
return { ...this.config };
|
|
32961
|
-
}
|
|
32962
|
-
/**
|
|
32963
|
-
* Get a default value
|
|
32964
|
-
* @param key - The key to get the default for
|
|
32965
|
-
*/
|
|
32966
|
-
getDefault(key) {
|
|
32967
|
-
return this.config?.defaults?.[key];
|
|
32968
|
-
}
|
|
32969
|
-
/**
|
|
32970
|
-
* Set a default value (mutates config.defaults)
|
|
32971
|
-
* @param key - The key to set the default for
|
|
32972
|
-
* @param value - The default value
|
|
32973
|
-
*/
|
|
32974
|
-
setDefault(key, value) {
|
|
32975
|
-
if (!this.config.defaults) {
|
|
32976
|
-
this.config.defaults = {};
|
|
32977
|
-
}
|
|
32978
|
-
this.config.defaults[key] = value;
|
|
32979
|
-
}
|
|
32980
|
-
/**
|
|
32981
|
-
* Set multiple default values
|
|
32982
|
-
* @param defaults - Record of default values
|
|
32983
|
-
*/
|
|
32984
|
-
setDefaults(defaults) {
|
|
32985
|
-
if (!this.config.defaults) {
|
|
32986
|
-
this.config.defaults = {};
|
|
32987
|
-
}
|
|
32988
|
-
Object.assign(this.config.defaults, defaults);
|
|
32989
|
-
}
|
|
32990
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
32991
|
-
// Assertions
|
|
32992
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
32993
|
-
/**
|
|
32994
|
-
* Assert that the service is available (configured and ready)
|
|
32995
|
-
* @throws CorePackageError if not available
|
|
32996
|
-
*/
|
|
32997
|
-
assertAvailable() {
|
|
32998
|
-
if (!this.isAvailable()) {
|
|
32999
|
-
throw new errors.CorePackageError(
|
|
33000
|
-
`${this.serviceName} is not available. Check configuration.`,
|
|
33001
|
-
errors$1.ERROR_CODES.CLIENT_INITIALIZATION_FAILED
|
|
33002
|
-
);
|
|
33003
|
-
}
|
|
33004
|
-
}
|
|
33005
|
-
/**
|
|
33006
|
-
* Assert that the service is enabled
|
|
33007
|
-
* @throws CorePackageError if disabled
|
|
33008
|
-
*/
|
|
33009
|
-
assertEnabled() {
|
|
33010
|
-
if (!this.isServiceEnabled) {
|
|
33011
|
-
throw new errors.CorePackageError(
|
|
33012
|
-
`${this.serviceName} is disabled. Set enabled: true in configuration.`,
|
|
33013
|
-
errors$1.ERROR_CODES.FEATURE_NOT_SUPPORTED
|
|
33014
|
-
);
|
|
33015
|
-
}
|
|
33016
|
-
}
|
|
33017
|
-
/**
|
|
33018
|
-
* Assert that the service is ready (enabled AND available)
|
|
33019
|
-
* @throws CorePackageError if not ready
|
|
33020
|
-
*/
|
|
33021
|
-
assertReady() {
|
|
33022
|
-
this.assertEnabled();
|
|
33023
|
-
this.assertAvailable();
|
|
33024
|
-
}
|
|
33025
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
33026
|
-
// Helper Methods
|
|
33027
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
33028
|
-
/**
|
|
33029
|
-
* Log debug message with service context
|
|
33030
|
-
*/
|
|
33031
|
-
logDebug(message, data) {
|
|
33032
|
-
this.logger.debug(message, {
|
|
33033
|
-
service: this.serviceName,
|
|
33034
|
-
...data
|
|
33035
|
-
});
|
|
33036
|
-
}
|
|
33037
|
-
/**
|
|
33038
|
-
* Log info message with service context
|
|
33039
|
-
*/
|
|
33040
|
-
logInfo(message, data) {
|
|
33041
|
-
this.logger.info(message, {
|
|
33042
|
-
service: this.serviceName,
|
|
33043
|
-
...data
|
|
33044
|
-
});
|
|
33045
|
-
}
|
|
33046
|
-
/**
|
|
33047
|
-
* Log warning message with service context
|
|
33048
|
-
*/
|
|
33049
|
-
logWarn(message, data) {
|
|
33050
|
-
this.logger.warn(message, {
|
|
33051
|
-
service: this.serviceName,
|
|
33052
|
-
...data
|
|
33053
|
-
});
|
|
33054
|
-
}
|
|
33055
|
-
/**
|
|
33056
|
-
* Log error message with service context
|
|
33057
|
-
*/
|
|
33058
|
-
logError(message, data) {
|
|
33059
|
-
this.logger.error(message, {
|
|
33060
|
-
service: this.serviceName,
|
|
33061
|
-
...data
|
|
33062
|
-
});
|
|
33063
|
-
}
|
|
33064
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
33065
|
-
// Observability Helpers
|
|
33066
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
33067
|
-
/**
|
|
33068
|
-
* Record a metric (no-op if observability not available)
|
|
33069
|
-
*/
|
|
33070
|
-
async recordMetric(name, value, tags) {
|
|
33071
|
-
if (!this.observabilityService) return;
|
|
33072
|
-
await this.observabilityService.recordHistogram(name, value, {
|
|
33073
|
-
service: this.serviceName,
|
|
33074
|
-
...tags
|
|
33075
|
-
});
|
|
33076
|
-
}
|
|
33077
|
-
/**
|
|
33078
|
-
* Increment a counter (no-op if observability not available)
|
|
33079
|
-
*/
|
|
33080
|
-
async incrementCounter(name, value = 1, tags) {
|
|
33081
|
-
if (!this.observabilityService) return;
|
|
33082
|
-
await this.observabilityService.incrementCounter(name, value, {
|
|
33083
|
-
service: this.serviceName,
|
|
33084
|
-
...tags
|
|
33085
|
-
});
|
|
33086
|
-
}
|
|
33087
|
-
/**
|
|
33088
|
-
* Start a span for tracing (returns noop span if observability not available)
|
|
33089
|
-
*/
|
|
33090
|
-
startSpan(name, attributes) {
|
|
33091
|
-
if (!this.observabilityService) {
|
|
33092
|
-
return {
|
|
33093
|
-
context: { traceId: "", spanId: "" },
|
|
33094
|
-
setAttribute: /* @__PURE__ */ __name(() => {
|
|
33095
|
-
}, "setAttribute"),
|
|
33096
|
-
setAttributes: /* @__PURE__ */ __name(() => {
|
|
33097
|
-
}, "setAttributes"),
|
|
33098
|
-
addEvent: /* @__PURE__ */ __name(() => {
|
|
33099
|
-
}, "addEvent"),
|
|
33100
|
-
setStatus: /* @__PURE__ */ __name(() => {
|
|
33101
|
-
}, "setStatus"),
|
|
33102
|
-
end: /* @__PURE__ */ __name(() => {
|
|
33103
|
-
}, "end"),
|
|
33104
|
-
recordException: /* @__PURE__ */ __name(() => {
|
|
33105
|
-
}, "recordException")
|
|
33106
|
-
};
|
|
33107
|
-
}
|
|
33108
|
-
return this.observabilityService.startSpan({
|
|
33109
|
-
name,
|
|
33110
|
-
attributes: {
|
|
33111
|
-
"service.name": this.serviceName,
|
|
33112
|
-
...attributes
|
|
33113
|
-
}
|
|
33114
|
-
});
|
|
33115
|
-
}
|
|
33116
|
-
/**
|
|
33117
|
-
* Execute a function within a traced span
|
|
33118
|
-
*/
|
|
33119
|
-
async withSpan(name, fn, attributes) {
|
|
33120
|
-
if (!this.observabilityService) {
|
|
33121
|
-
const noopSpan = this.startSpan(name);
|
|
33122
|
-
return fn(noopSpan);
|
|
33123
|
-
}
|
|
33124
|
-
return this.observabilityService.withSpan(
|
|
33125
|
-
{
|
|
33126
|
-
name,
|
|
33127
|
-
attributes: {
|
|
33128
|
-
"service.name": this.serviceName,
|
|
33129
|
-
...attributes
|
|
33130
|
-
}
|
|
33131
|
-
},
|
|
33132
|
-
fn
|
|
33133
|
-
);
|
|
33134
|
-
}
|
|
33135
|
-
};
|
|
33136
32738
|
function hashString(str) {
|
|
33137
32739
|
if (str.length === 0) return 0;
|
|
33138
32740
|
let hash = config.FNV_CONSTANTS.FNV_32_OFFSET;
|
|
@@ -35710,6 +35312,13 @@ var Core = class _Core {
|
|
|
35710
35312
|
_Core._logger = null;
|
|
35711
35313
|
}
|
|
35712
35314
|
}
|
|
35315
|
+
/**
|
|
35316
|
+
* Get the configured logger transport.
|
|
35317
|
+
* Used by services to create loggers with the same transport setting.
|
|
35318
|
+
*/
|
|
35319
|
+
static get loggerTransport() {
|
|
35320
|
+
return _Core._loggerTransport;
|
|
35321
|
+
}
|
|
35713
35322
|
/**
|
|
35714
35323
|
* Log a message during initialization.
|
|
35715
35324
|
* Uses PackageLogger, respects verbose flag.
|
|
@@ -36985,8 +36594,405 @@ var Core = class _Core {
|
|
|
36985
36594
|
_Core.log("Feature flags initialized", verbose);
|
|
36986
36595
|
}
|
|
36987
36596
|
};
|
|
36988
|
-
|
|
36989
|
-
//
|
|
36597
|
+
var BaseDomainService = class {
|
|
36598
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36599
|
+
// Constructor
|
|
36600
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36601
|
+
/**
|
|
36602
|
+
* Create a new domain service instance
|
|
36603
|
+
*
|
|
36604
|
+
* @param config - Base service configuration (passed via super({...}))
|
|
36605
|
+
*/
|
|
36606
|
+
// eslint-disable-next-line complexity
|
|
36607
|
+
constructor(config) {
|
|
36608
|
+
/** Initialization state */
|
|
36609
|
+
this._initialized = false;
|
|
36610
|
+
// API Client (optional)
|
|
36611
|
+
this._apiClient = null;
|
|
36612
|
+
this._clientInitPromise = null;
|
|
36613
|
+
/**
|
|
36614
|
+
* Cache prefix for namespacing cache keys (e.g., 'example', 'user', 'product').
|
|
36615
|
+
* Subclasses can override by defining as a property.
|
|
36616
|
+
* If not overridden, defaults to serviceName.toLowerCase().
|
|
36617
|
+
*
|
|
36618
|
+
* @example
|
|
36619
|
+
* ```typescript
|
|
36620
|
+
* protected cachePrefix = 'my-service'; // Override default
|
|
36621
|
+
* ```
|
|
36622
|
+
*/
|
|
36623
|
+
this.cachePrefix = "";
|
|
36624
|
+
// Mapper and Validator instances (lazy)
|
|
36625
|
+
this._mapperInstance = null;
|
|
36626
|
+
this._validatorInstance = null;
|
|
36627
|
+
this.serviceName = config.serviceName;
|
|
36628
|
+
this.supportedRuntimes = config.supportedRuntimes;
|
|
36629
|
+
this.config = config.serviceConfig;
|
|
36630
|
+
this._setAsDefaultClient = config.setAsDefaultClient ?? false;
|
|
36631
|
+
this.logger = new logger$1.PackageLogger({
|
|
36632
|
+
packageName: "core",
|
|
36633
|
+
service: this.serviceName,
|
|
36634
|
+
transport: Core.loggerTransport
|
|
36635
|
+
});
|
|
36636
|
+
this._apiClientConfig = config.apiClientConfig;
|
|
36637
|
+
this.cacheManager = config.injected?.cache;
|
|
36638
|
+
this.dbService = config.injected?.db;
|
|
36639
|
+
this.apiService = config.injected?.api;
|
|
36640
|
+
this.observabilityService = config.serviceConfig.observabilityOverride ?? config.injected?.observability;
|
|
36641
|
+
if (!this.cachePrefix) {
|
|
36642
|
+
this.cachePrefix = this.serviceName.toLowerCase();
|
|
36643
|
+
}
|
|
36644
|
+
this._MapperClass = config.mapperClass;
|
|
36645
|
+
this._ValidatorClass = config.validatorClass;
|
|
36646
|
+
if (this._apiClientConfig) {
|
|
36647
|
+
this.initializeApiClient();
|
|
36648
|
+
}
|
|
36649
|
+
this.logger.debug(`${this.serviceName} created`, {
|
|
36650
|
+
supportedRuntimes: this.supportedRuntimes,
|
|
36651
|
+
hasApiClient: !!this._apiClientConfig,
|
|
36652
|
+
injected: {
|
|
36653
|
+
cache: !!this.cacheManager,
|
|
36654
|
+
db: !!this.dbService,
|
|
36655
|
+
api: !!this.apiService,
|
|
36656
|
+
observability: !!this.observabilityService
|
|
36657
|
+
},
|
|
36658
|
+
cachePrefix: this.cachePrefix,
|
|
36659
|
+
hasMapper: !!this._MapperClass,
|
|
36660
|
+
hasValidator: !!this._ValidatorClass
|
|
36661
|
+
});
|
|
36662
|
+
}
|
|
36663
|
+
static {
|
|
36664
|
+
__name(this, "BaseDomainService");
|
|
36665
|
+
}
|
|
36666
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36667
|
+
// Getters
|
|
36668
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36669
|
+
/**
|
|
36670
|
+
* Check if the service is enabled
|
|
36671
|
+
* Service is enabled by default unless explicitly disabled
|
|
36672
|
+
*/
|
|
36673
|
+
get isServiceEnabled() {
|
|
36674
|
+
return this.config?.enabled !== false;
|
|
36675
|
+
}
|
|
36676
|
+
/**
|
|
36677
|
+
* Check if the service is initialized (API client ready)
|
|
36678
|
+
*/
|
|
36679
|
+
get isInitialized() {
|
|
36680
|
+
return this._initialized;
|
|
36681
|
+
}
|
|
36682
|
+
/**
|
|
36683
|
+
* Check if mapper is available
|
|
36684
|
+
*/
|
|
36685
|
+
get hasMapper() {
|
|
36686
|
+
return !!this._MapperClass;
|
|
36687
|
+
}
|
|
36688
|
+
/**
|
|
36689
|
+
* Check if validator is available
|
|
36690
|
+
*/
|
|
36691
|
+
get hasValidator() {
|
|
36692
|
+
return !!this._ValidatorClass;
|
|
36693
|
+
}
|
|
36694
|
+
/**
|
|
36695
|
+
* Get the mapper instance (lazy initialization)
|
|
36696
|
+
* @throws CorePackageError if MapperClass was not provided
|
|
36697
|
+
*/
|
|
36698
|
+
get mapper() {
|
|
36699
|
+
if (!this._mapperInstance && this._MapperClass) {
|
|
36700
|
+
this._mapperInstance = new this._MapperClass();
|
|
36701
|
+
}
|
|
36702
|
+
if (!this._mapperInstance) {
|
|
36703
|
+
throw new errors.CorePackageError(
|
|
36704
|
+
`${this.serviceName} does not have a Mapper configured`,
|
|
36705
|
+
errors$1.ERROR_CODES.FEATURE_NOT_SUPPORTED
|
|
36706
|
+
);
|
|
36707
|
+
}
|
|
36708
|
+
return this._mapperInstance;
|
|
36709
|
+
}
|
|
36710
|
+
/**
|
|
36711
|
+
* Set the mapper instance
|
|
36712
|
+
* Allows subclasses to override mapper initialization
|
|
36713
|
+
*/
|
|
36714
|
+
set mapper(value) {
|
|
36715
|
+
this._mapperInstance = value;
|
|
36716
|
+
}
|
|
36717
|
+
/**
|
|
36718
|
+
* Get the validator instance (lazy initialization)
|
|
36719
|
+
* @throws CorePackageError if ValidatorClass was not provided
|
|
36720
|
+
*/
|
|
36721
|
+
get validator() {
|
|
36722
|
+
if (!this._validatorInstance && this._ValidatorClass) {
|
|
36723
|
+
this._validatorInstance = new this._ValidatorClass();
|
|
36724
|
+
}
|
|
36725
|
+
if (!this._validatorInstance) {
|
|
36726
|
+
throw new errors.CorePackageError(
|
|
36727
|
+
`${this.serviceName} does not have a Validator configured`,
|
|
36728
|
+
errors$1.ERROR_CODES.FEATURE_NOT_SUPPORTED
|
|
36729
|
+
);
|
|
36730
|
+
}
|
|
36731
|
+
return this._validatorInstance;
|
|
36732
|
+
}
|
|
36733
|
+
/**
|
|
36734
|
+
* Set the validator instance
|
|
36735
|
+
* Allows subclasses to override validator initialization
|
|
36736
|
+
*/
|
|
36737
|
+
set validator(value) {
|
|
36738
|
+
this._validatorInstance = value;
|
|
36739
|
+
}
|
|
36740
|
+
/**
|
|
36741
|
+
* Get the API client (after initialization)
|
|
36742
|
+
* @throws CorePackageError if API client was not configured or not initialized
|
|
36743
|
+
*/
|
|
36744
|
+
get apiClient() {
|
|
36745
|
+
if (!this._apiClient) {
|
|
36746
|
+
throw new errors.CorePackageError(
|
|
36747
|
+
`${this.serviceName} API client not initialized. Call ensureApiClientInitialized() first.`,
|
|
36748
|
+
errors$1.ERROR_CODES.CLIENT_INITIALIZATION_FAILED
|
|
36749
|
+
);
|
|
36750
|
+
}
|
|
36751
|
+
return this._apiClient;
|
|
36752
|
+
}
|
|
36753
|
+
/**
|
|
36754
|
+
* Get the observability adapter (if injected)
|
|
36755
|
+
* Returns undefined if observability is not enabled
|
|
36756
|
+
*/
|
|
36757
|
+
get observability() {
|
|
36758
|
+
return this.observabilityService;
|
|
36759
|
+
}
|
|
36760
|
+
/**
|
|
36761
|
+
* Check if observability is available
|
|
36762
|
+
*/
|
|
36763
|
+
get hasObservability() {
|
|
36764
|
+
return !!this.observabilityService;
|
|
36765
|
+
}
|
|
36766
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36767
|
+
// API Client Initialization
|
|
36768
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36769
|
+
/**
|
|
36770
|
+
* Initialize API client asynchronously
|
|
36771
|
+
* Called from constructor if apiClientConfig is provided
|
|
36772
|
+
*/
|
|
36773
|
+
initializeApiClient() {
|
|
36774
|
+
if (this._clientInitPromise || !this._apiClientConfig) {
|
|
36775
|
+
return;
|
|
36776
|
+
}
|
|
36777
|
+
this._clientInitPromise = (async () => {
|
|
36778
|
+
try {
|
|
36779
|
+
this._apiClient = await frontend.createApiClient(this._apiClientConfig);
|
|
36780
|
+
if (this._setAsDefaultClient) {
|
|
36781
|
+
frontend.setDefaultApiClient(this._apiClient);
|
|
36782
|
+
}
|
|
36783
|
+
this._initialized = true;
|
|
36784
|
+
this.logger.debug("API client initialized", {
|
|
36785
|
+
service: this.serviceName,
|
|
36786
|
+
baseURL: this._apiClientConfig.baseURL
|
|
36787
|
+
});
|
|
36788
|
+
} catch (error) {
|
|
36789
|
+
this.logger.error("Failed to initialize API client", {
|
|
36790
|
+
service: this.serviceName,
|
|
36791
|
+
error: error instanceof Error ? error.message : String(error)
|
|
36792
|
+
});
|
|
36793
|
+
throw error;
|
|
36794
|
+
}
|
|
36795
|
+
})();
|
|
36796
|
+
}
|
|
36797
|
+
/**
|
|
36798
|
+
* Ensure API client is initialized before use.
|
|
36799
|
+
* Call this from methods that need the API client.
|
|
36800
|
+
* Also called by ServiceRegistry.create() for services with async initialization.
|
|
36801
|
+
*/
|
|
36802
|
+
async ensureApiClientInitialized() {
|
|
36803
|
+
if (this._clientInitPromise) {
|
|
36804
|
+
await this._clientInitPromise;
|
|
36805
|
+
}
|
|
36806
|
+
if (this._apiClientConfig && !this._apiClient) {
|
|
36807
|
+
throw new errors.CorePackageError(
|
|
36808
|
+
`${this.serviceName} API client not initialized`,
|
|
36809
|
+
errors$1.ERROR_CODES.CLIENT_INITIALIZATION_FAILED
|
|
36810
|
+
);
|
|
36811
|
+
}
|
|
36812
|
+
}
|
|
36813
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36814
|
+
// Configuration Management
|
|
36815
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36816
|
+
/**
|
|
36817
|
+
* Get current configuration (immutable copy)
|
|
36818
|
+
*/
|
|
36819
|
+
getConfig() {
|
|
36820
|
+
return { ...this.config };
|
|
36821
|
+
}
|
|
36822
|
+
/**
|
|
36823
|
+
* Get a default value
|
|
36824
|
+
* @param key - The key to get the default for
|
|
36825
|
+
*/
|
|
36826
|
+
getDefault(key) {
|
|
36827
|
+
return this.config?.defaults?.[key];
|
|
36828
|
+
}
|
|
36829
|
+
/**
|
|
36830
|
+
* Set a default value (mutates config.defaults)
|
|
36831
|
+
* @param key - The key to set the default for
|
|
36832
|
+
* @param value - The default value
|
|
36833
|
+
*/
|
|
36834
|
+
setDefault(key, value) {
|
|
36835
|
+
if (!this.config.defaults) {
|
|
36836
|
+
this.config.defaults = {};
|
|
36837
|
+
}
|
|
36838
|
+
this.config.defaults[key] = value;
|
|
36839
|
+
}
|
|
36840
|
+
/**
|
|
36841
|
+
* Set multiple default values
|
|
36842
|
+
* @param defaults - Record of default values
|
|
36843
|
+
*/
|
|
36844
|
+
setDefaults(defaults) {
|
|
36845
|
+
if (!this.config.defaults) {
|
|
36846
|
+
this.config.defaults = {};
|
|
36847
|
+
}
|
|
36848
|
+
Object.assign(this.config.defaults, defaults);
|
|
36849
|
+
}
|
|
36850
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36851
|
+
// Assertions
|
|
36852
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36853
|
+
/**
|
|
36854
|
+
* Assert that the service is available (configured and ready)
|
|
36855
|
+
* @throws CorePackageError if not available
|
|
36856
|
+
*/
|
|
36857
|
+
assertAvailable() {
|
|
36858
|
+
if (!this.isAvailable()) {
|
|
36859
|
+
throw new errors.CorePackageError(
|
|
36860
|
+
`${this.serviceName} is not available. Check configuration.`,
|
|
36861
|
+
errors$1.ERROR_CODES.CLIENT_INITIALIZATION_FAILED
|
|
36862
|
+
);
|
|
36863
|
+
}
|
|
36864
|
+
}
|
|
36865
|
+
/**
|
|
36866
|
+
* Assert that the service is enabled
|
|
36867
|
+
* @throws CorePackageError if disabled
|
|
36868
|
+
*/
|
|
36869
|
+
assertEnabled() {
|
|
36870
|
+
if (!this.isServiceEnabled) {
|
|
36871
|
+
throw new errors.CorePackageError(
|
|
36872
|
+
`${this.serviceName} is disabled. Set enabled: true in configuration.`,
|
|
36873
|
+
errors$1.ERROR_CODES.FEATURE_NOT_SUPPORTED
|
|
36874
|
+
);
|
|
36875
|
+
}
|
|
36876
|
+
}
|
|
36877
|
+
/**
|
|
36878
|
+
* Assert that the service is ready (enabled AND available)
|
|
36879
|
+
* @throws CorePackageError if not ready
|
|
36880
|
+
*/
|
|
36881
|
+
assertReady() {
|
|
36882
|
+
this.assertEnabled();
|
|
36883
|
+
this.assertAvailable();
|
|
36884
|
+
}
|
|
36885
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36886
|
+
// Helper Methods
|
|
36887
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36888
|
+
/**
|
|
36889
|
+
* Log debug message with service context
|
|
36890
|
+
*/
|
|
36891
|
+
logDebug(message, data) {
|
|
36892
|
+
this.logger.debug(message, {
|
|
36893
|
+
service: this.serviceName,
|
|
36894
|
+
...data
|
|
36895
|
+
});
|
|
36896
|
+
}
|
|
36897
|
+
/**
|
|
36898
|
+
* Log info message with service context
|
|
36899
|
+
*/
|
|
36900
|
+
logInfo(message, data) {
|
|
36901
|
+
this.logger.info(message, {
|
|
36902
|
+
service: this.serviceName,
|
|
36903
|
+
...data
|
|
36904
|
+
});
|
|
36905
|
+
}
|
|
36906
|
+
/**
|
|
36907
|
+
* Log warning message with service context
|
|
36908
|
+
*/
|
|
36909
|
+
logWarn(message, data) {
|
|
36910
|
+
this.logger.warn(message, {
|
|
36911
|
+
service: this.serviceName,
|
|
36912
|
+
...data
|
|
36913
|
+
});
|
|
36914
|
+
}
|
|
36915
|
+
/**
|
|
36916
|
+
* Log error message with service context
|
|
36917
|
+
*/
|
|
36918
|
+
logError(message, data) {
|
|
36919
|
+
this.logger.error(message, {
|
|
36920
|
+
service: this.serviceName,
|
|
36921
|
+
...data
|
|
36922
|
+
});
|
|
36923
|
+
}
|
|
36924
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36925
|
+
// Observability Helpers
|
|
36926
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
36927
|
+
/**
|
|
36928
|
+
* Record a metric (no-op if observability not available)
|
|
36929
|
+
*/
|
|
36930
|
+
async recordMetric(name, value, tags) {
|
|
36931
|
+
if (!this.observabilityService) return;
|
|
36932
|
+
await this.observabilityService.recordHistogram(name, value, {
|
|
36933
|
+
service: this.serviceName,
|
|
36934
|
+
...tags
|
|
36935
|
+
});
|
|
36936
|
+
}
|
|
36937
|
+
/**
|
|
36938
|
+
* Increment a counter (no-op if observability not available)
|
|
36939
|
+
*/
|
|
36940
|
+
async incrementCounter(name, value = 1, tags) {
|
|
36941
|
+
if (!this.observabilityService) return;
|
|
36942
|
+
await this.observabilityService.incrementCounter(name, value, {
|
|
36943
|
+
service: this.serviceName,
|
|
36944
|
+
...tags
|
|
36945
|
+
});
|
|
36946
|
+
}
|
|
36947
|
+
/**
|
|
36948
|
+
* Start a span for tracing (returns noop span if observability not available)
|
|
36949
|
+
*/
|
|
36950
|
+
startSpan(name, attributes) {
|
|
36951
|
+
if (!this.observabilityService) {
|
|
36952
|
+
return {
|
|
36953
|
+
context: { traceId: "", spanId: "" },
|
|
36954
|
+
setAttribute: /* @__PURE__ */ __name(() => {
|
|
36955
|
+
}, "setAttribute"),
|
|
36956
|
+
setAttributes: /* @__PURE__ */ __name(() => {
|
|
36957
|
+
}, "setAttributes"),
|
|
36958
|
+
addEvent: /* @__PURE__ */ __name(() => {
|
|
36959
|
+
}, "addEvent"),
|
|
36960
|
+
setStatus: /* @__PURE__ */ __name(() => {
|
|
36961
|
+
}, "setStatus"),
|
|
36962
|
+
end: /* @__PURE__ */ __name(() => {
|
|
36963
|
+
}, "end"),
|
|
36964
|
+
recordException: /* @__PURE__ */ __name(() => {
|
|
36965
|
+
}, "recordException")
|
|
36966
|
+
};
|
|
36967
|
+
}
|
|
36968
|
+
return this.observabilityService.startSpan({
|
|
36969
|
+
name,
|
|
36970
|
+
attributes: {
|
|
36971
|
+
"service.name": this.serviceName,
|
|
36972
|
+
...attributes
|
|
36973
|
+
}
|
|
36974
|
+
});
|
|
36975
|
+
}
|
|
36976
|
+
/**
|
|
36977
|
+
* Execute a function within a traced span
|
|
36978
|
+
*/
|
|
36979
|
+
async withSpan(name, fn, attributes) {
|
|
36980
|
+
if (!this.observabilityService) {
|
|
36981
|
+
const noopSpan = this.startSpan(name);
|
|
36982
|
+
return fn(noopSpan);
|
|
36983
|
+
}
|
|
36984
|
+
return this.observabilityService.withSpan(
|
|
36985
|
+
{
|
|
36986
|
+
name,
|
|
36987
|
+
attributes: {
|
|
36988
|
+
"service.name": this.serviceName,
|
|
36989
|
+
...attributes
|
|
36990
|
+
}
|
|
36991
|
+
},
|
|
36992
|
+
fn
|
|
36993
|
+
);
|
|
36994
|
+
}
|
|
36995
|
+
};
|
|
36990
36996
|
var BaseFrontendDomainService = class extends BaseDomainService {
|
|
36991
36997
|
// ─────────────────────────────────────────────────────────────────────────
|
|
36992
36998
|
// Constructor
|
|
@@ -37406,6 +37412,94 @@ var BaseFrontendDomainService = class extends BaseDomainService {
|
|
|
37406
37412
|
}
|
|
37407
37413
|
return result2;
|
|
37408
37414
|
}
|
|
37415
|
+
/**
|
|
37416
|
+
* Check if a response indicates success.
|
|
37417
|
+
*
|
|
37418
|
+
* Uses `responseSuccessKey` config if set, otherwise auto-detects from:
|
|
37419
|
+
* - `isSuccess` (internal format)
|
|
37420
|
+
* - `success` (alternative internal format)
|
|
37421
|
+
* - `ok` (fetchff/fetch standard)
|
|
37422
|
+
* - HTTP status code 200-299
|
|
37423
|
+
*
|
|
37424
|
+
* Supports nested keys via dot notation (e.g., `'meta.success'`).
|
|
37425
|
+
*
|
|
37426
|
+
* @param response - Response object from fetcher
|
|
37427
|
+
* @returns true if response indicates success
|
|
37428
|
+
*/
|
|
37429
|
+
// eslint-disable-next-line complexity
|
|
37430
|
+
isResponseSuccess(response) {
|
|
37431
|
+
if (!response || typeof response !== "object") {
|
|
37432
|
+
return false;
|
|
37433
|
+
}
|
|
37434
|
+
const resp = response;
|
|
37435
|
+
const successKey = this.config.responseSuccessKey;
|
|
37436
|
+
if (successKey) {
|
|
37437
|
+
const keys = successKey.split(".");
|
|
37438
|
+
let result2 = resp;
|
|
37439
|
+
for (const k of keys) {
|
|
37440
|
+
if (result2 && typeof result2 === "object" && k in result2) {
|
|
37441
|
+
result2 = result2[k];
|
|
37442
|
+
} else {
|
|
37443
|
+
break;
|
|
37444
|
+
}
|
|
37445
|
+
}
|
|
37446
|
+
if (typeof result2 === "boolean") {
|
|
37447
|
+
return result2;
|
|
37448
|
+
}
|
|
37449
|
+
}
|
|
37450
|
+
if ("isSuccess" in resp && typeof resp.isSuccess === "boolean") {
|
|
37451
|
+
return resp.isSuccess;
|
|
37452
|
+
}
|
|
37453
|
+
if ("success" in resp && typeof resp.success === "boolean") {
|
|
37454
|
+
return resp.success;
|
|
37455
|
+
}
|
|
37456
|
+
if ("ok" in resp && typeof resp.ok === "boolean") {
|
|
37457
|
+
return resp.ok;
|
|
37458
|
+
}
|
|
37459
|
+
if ("status" in resp && typeof resp.status === "number") {
|
|
37460
|
+
return resp.status >= types.HTTP_STATUS.OK && resp.status < types.HTTP_STATUS.MULTIPLE_CHOICES;
|
|
37461
|
+
}
|
|
37462
|
+
return "data" in resp && !("error" in resp && resp.error);
|
|
37463
|
+
}
|
|
37464
|
+
/**
|
|
37465
|
+
* Extract error from API response.
|
|
37466
|
+
*
|
|
37467
|
+
* Uses `responseErrorKey` config if set, otherwise auto-detects from:
|
|
37468
|
+
* - `error` (common format)
|
|
37469
|
+
* - `errors` (array format, e.g., GraphQL)
|
|
37470
|
+
*
|
|
37471
|
+
* Supports nested keys via dot notation (e.g., `'meta.error'`).
|
|
37472
|
+
*
|
|
37473
|
+
* @param response - Response object from fetcher
|
|
37474
|
+
* @returns Extracted error or undefined if not found
|
|
37475
|
+
*/
|
|
37476
|
+
// eslint-disable-next-line complexity
|
|
37477
|
+
extractResponseError(response) {
|
|
37478
|
+
if (!response || typeof response !== "object") {
|
|
37479
|
+
return void 0;
|
|
37480
|
+
}
|
|
37481
|
+
const resp = response;
|
|
37482
|
+
const errorKey = this.config.responseErrorKey;
|
|
37483
|
+
if (errorKey) {
|
|
37484
|
+
const keys = errorKey.split(".");
|
|
37485
|
+
let result2 = resp;
|
|
37486
|
+
for (const k of keys) {
|
|
37487
|
+
if (result2 && typeof result2 === "object" && k in result2) {
|
|
37488
|
+
result2 = result2[k];
|
|
37489
|
+
} else {
|
|
37490
|
+
return void 0;
|
|
37491
|
+
}
|
|
37492
|
+
}
|
|
37493
|
+
return result2;
|
|
37494
|
+
}
|
|
37495
|
+
if ("error" in resp && resp.error) {
|
|
37496
|
+
return resp.error;
|
|
37497
|
+
}
|
|
37498
|
+
if ("errors" in resp && resp.errors) {
|
|
37499
|
+
return resp.errors;
|
|
37500
|
+
}
|
|
37501
|
+
return void 0;
|
|
37502
|
+
}
|
|
37409
37503
|
// ─────────────────────────────────────────────────────────────────────────
|
|
37410
37504
|
// Generic CRUD Operations
|
|
37411
37505
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -37461,13 +37555,15 @@ var BaseFrontendDomainService = class extends BaseDomainService {
|
|
|
37461
37555
|
try {
|
|
37462
37556
|
await this.beforeFetchAll?.(query);
|
|
37463
37557
|
const response = await this.config.fetchers.fetchAll(query, options);
|
|
37464
|
-
if (!response
|
|
37558
|
+
if (!this.isResponseSuccess(response)) {
|
|
37559
|
+
const extractedError = this.extractResponseError(response);
|
|
37465
37560
|
throw new errors.CorePackageError(
|
|
37466
37561
|
"Failed to fetch entities",
|
|
37467
37562
|
errors$1.ERROR_CODES.CONTEXT_OPERATION_FAILED,
|
|
37468
37563
|
{
|
|
37469
37564
|
context: { operation: "fetchAll", query },
|
|
37470
|
-
cause:
|
|
37565
|
+
cause: extractedError instanceof Error ? extractedError : void 0,
|
|
37566
|
+
details: extractedError
|
|
37471
37567
|
}
|
|
37472
37568
|
);
|
|
37473
37569
|
}
|
|
@@ -37515,13 +37611,16 @@ var BaseFrontendDomainService = class extends BaseDomainService {
|
|
|
37515
37611
|
try {
|
|
37516
37612
|
await this.beforeFetchById?.(id);
|
|
37517
37613
|
const response = await this.config.fetchers.fetchById(String(id), options);
|
|
37518
|
-
if (!response
|
|
37519
|
-
|
|
37614
|
+
if (!this.isResponseSuccess(response)) {
|
|
37615
|
+
const extractedError = this.extractResponseError(response);
|
|
37616
|
+
const errorMessage = extractedError instanceof Error ? extractedError.message : String(extractedError ?? "");
|
|
37617
|
+
if (errorMessage.includes("404") || response.status === types.HTTP_STATUS.NOT_FOUND) {
|
|
37520
37618
|
return null;
|
|
37521
37619
|
}
|
|
37522
37620
|
throw new errors.CorePackageError("Failed to fetch entity", errors$1.ERROR_CODES.CONTEXT_OPERATION_FAILED, {
|
|
37523
37621
|
context: { operation: "fetchById", entityId: String(id) },
|
|
37524
|
-
cause:
|
|
37622
|
+
cause: extractedError instanceof Error ? extractedError : void 0,
|
|
37623
|
+
details: extractedError
|
|
37525
37624
|
});
|
|
37526
37625
|
}
|
|
37527
37626
|
const rawData = this.unwrapResponseData(response.data);
|
|
@@ -37597,15 +37696,14 @@ var BaseFrontendDomainService = class extends BaseDomainService {
|
|
|
37597
37696
|
});
|
|
37598
37697
|
}
|
|
37599
37698
|
const response = await this.config.fetchers.create(createDTO, options);
|
|
37600
|
-
if (!response
|
|
37601
|
-
|
|
37602
|
-
|
|
37603
|
-
|
|
37604
|
-
{
|
|
37605
|
-
|
|
37606
|
-
|
|
37607
|
-
|
|
37608
|
-
);
|
|
37699
|
+
if (!this.isResponseSuccess(response)) {
|
|
37700
|
+
const extractedError = this.extractResponseError(response);
|
|
37701
|
+
const errorMessage = extractedError instanceof Error ? extractedError.message : typeof extractedError === "string" ? extractedError : "Failed to create entity";
|
|
37702
|
+
throw new errors.CorePackageError(errorMessage, errors$1.ERROR_CODES.CONTEXT_OPERATION_FAILED, {
|
|
37703
|
+
context: { operation: "create" },
|
|
37704
|
+
cause: extractedError instanceof Error ? extractedError : void 0,
|
|
37705
|
+
details: extractedError
|
|
37706
|
+
});
|
|
37609
37707
|
}
|
|
37610
37708
|
const rawData = this.unwrapResponseData(response.data);
|
|
37611
37709
|
const entity = this.mapper.toDomain(rawData);
|
|
@@ -37691,15 +37789,14 @@ var BaseFrontendDomainService = class extends BaseDomainService {
|
|
|
37691
37789
|
});
|
|
37692
37790
|
}
|
|
37693
37791
|
const response = await this.config.fetchers.update({ id, data: patchDTO }, options);
|
|
37694
|
-
if (!response
|
|
37695
|
-
|
|
37696
|
-
|
|
37697
|
-
|
|
37698
|
-
{
|
|
37699
|
-
|
|
37700
|
-
|
|
37701
|
-
|
|
37702
|
-
);
|
|
37792
|
+
if (!this.isResponseSuccess(response)) {
|
|
37793
|
+
const extractedError = this.extractResponseError(response);
|
|
37794
|
+
const errorMessage = extractedError instanceof Error ? extractedError.message : typeof extractedError === "string" ? extractedError : "Failed to update entity";
|
|
37795
|
+
throw new errors.CorePackageError(errorMessage, errors$1.ERROR_CODES.CONTEXT_OPERATION_FAILED, {
|
|
37796
|
+
context: { operation: "update", entityId: id },
|
|
37797
|
+
cause: extractedError instanceof Error ? extractedError : void 0,
|
|
37798
|
+
details: extractedError
|
|
37799
|
+
});
|
|
37703
37800
|
}
|
|
37704
37801
|
const rawData = this.unwrapResponseData(response.data);
|
|
37705
37802
|
const serverEntity = this.mapper.toDomain(rawData);
|
|
@@ -37771,15 +37868,14 @@ var BaseFrontendDomainService = class extends BaseDomainService {
|
|
|
37771
37868
|
});
|
|
37772
37869
|
}
|
|
37773
37870
|
const response = await this.config.fetchers.delete(String(id), options);
|
|
37774
|
-
if (!response
|
|
37775
|
-
|
|
37776
|
-
|
|
37777
|
-
|
|
37778
|
-
{
|
|
37779
|
-
|
|
37780
|
-
|
|
37781
|
-
|
|
37782
|
-
);
|
|
37871
|
+
if (!this.isResponseSuccess(response)) {
|
|
37872
|
+
const extractedError = this.extractResponseError(response);
|
|
37873
|
+
const errorMessage = extractedError instanceof Error ? extractedError.message : typeof extractedError === "string" ? extractedError : "Failed to delete entity";
|
|
37874
|
+
throw new errors.CorePackageError(errorMessage, errors$1.ERROR_CODES.CONTEXT_OPERATION_FAILED, {
|
|
37875
|
+
context: { operation: "delete", entityId: String(id) },
|
|
37876
|
+
cause: extractedError instanceof Error ? extractedError : void 0,
|
|
37877
|
+
details: extractedError
|
|
37878
|
+
});
|
|
37783
37879
|
}
|
|
37784
37880
|
if (!isOptimistic) {
|
|
37785
37881
|
this.removeEntityFromStore(String(id));
|
|
@@ -44672,6 +44768,8 @@ var ExampleMapperClass = class extends BaseMapper {
|
|
|
44672
44768
|
* API DTO → Domain Model
|
|
44673
44769
|
*/
|
|
44674
44770
|
toDomain(dto) {
|
|
44771
|
+
const createdAt = dto.created_at ? new Date(dto.created_at) : /* @__PURE__ */ new Date();
|
|
44772
|
+
const updatedAt = dto.updated_at ? new Date(dto.updated_at) : /* @__PURE__ */ new Date();
|
|
44675
44773
|
return {
|
|
44676
44774
|
id: dto.id,
|
|
44677
44775
|
name: dto.name,
|
|
@@ -44680,8 +44778,8 @@ var ExampleMapperClass = class extends BaseMapper {
|
|
|
44680
44778
|
status: dto.status,
|
|
44681
44779
|
amount: dto.amount,
|
|
44682
44780
|
isVisible: dto.is_visible,
|
|
44683
|
-
createdAt: new Date(
|
|
44684
|
-
updatedAt: new Date(
|
|
44781
|
+
createdAt: isNaN(createdAt.getTime()) ? /* @__PURE__ */ new Date() : createdAt,
|
|
44782
|
+
updatedAt: isNaN(updatedAt.getTime()) ? /* @__PURE__ */ new Date() : updatedAt,
|
|
44685
44783
|
// Computed properties
|
|
44686
44784
|
isActive: dto.status === "active",
|
|
44687
44785
|
hasDescription: /* @__PURE__ */ __name(() => Boolean(dto.description), "hasDescription")
|
|
@@ -45115,6 +45213,7 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
|
|
|
45115
45213
|
// ─────────────────────────────────────────────────────────────────────────
|
|
45116
45214
|
// Constructor
|
|
45117
45215
|
// ─────────────────────────────────────────────────────────────────────────
|
|
45216
|
+
// eslint-disable-next-line complexity
|
|
45118
45217
|
constructor(config = {}, options) {
|
|
45119
45218
|
const apiBasePath = config.apiBasePath ?? "/api/examples";
|
|
45120
45219
|
super({
|
|
@@ -45128,8 +45227,12 @@ var FrontendExampleDomainService = class _FrontendExampleDomainService extends B
|
|
|
45128
45227
|
autoFetch: false,
|
|
45129
45228
|
pollingInterval: 0,
|
|
45130
45229
|
...config,
|
|
45131
|
-
//
|
|
45132
|
-
//
|
|
45230
|
+
// Fetchff response format: { ok, status, data: { success, message, data, codeStatus }, error }
|
|
45231
|
+
// Use 'ok' for success check (HTTP level)
|
|
45232
|
+
responseSuccessKey: "ok",
|
|
45233
|
+
// Extract error from fetchff response
|
|
45234
|
+
responseErrorKey: "error",
|
|
45235
|
+
// Unwrap SuccessResponseStandard: extract 'data' from response.data
|
|
45133
45236
|
responseDataKey: "data",
|
|
45134
45237
|
// Fetchers - using apiClient directly for testing/example purposes
|
|
45135
45238
|
// In production, these would be imported from @plyaz/api services
|