pict 1.0.388 → 1.0.390
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/pict.js +20 -3
- package/dist/pict.js.map +1 -1
- package/dist/pict.min.js +1 -1
- package/dist/pict.min.js.map +1 -1
- package/package.json +1 -1
- package/source/Pict-Meadow-EntityProvider.js +37 -4
- package/types/source/Pict-Meadow-EntityProvider.d.ts +15 -0
- package/types/source/Pict-Meadow-EntityProvider.d.ts.map +1 -1
package/dist/pict.js
CHANGED
|
@@ -6218,7 +6218,7 @@ try{if(!global.localStorage)return false;}catch(_){return false;}var val=global.
|
|
|
6218
6218
|
// presumably different callback function.
|
|
6219
6219
|
// This makes sure that own properties are retained, so that
|
|
6220
6220
|
// decorations and such are not lost along the way.
|
|
6221
|
-
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],191:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],192:[function(require,module,exports){module.exports={"name":"pict","version":"1.0.
|
|
6221
|
+
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],191:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],192:[function(require,module,exports){module.exports={"name":"pict","version":"1.0.390","description":"Pict browser library.","main":"source/Pict.js","scripts":{"start":"node source/Pict.js","test":"npx quack test","tests":"npx quack test -g","coverage":"npx quack coverage","build":"npx quack build","prepublishOnly":"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t pict-image:local","docker-dev-run":"docker run -it -d --name pict-dev -p 37447:8080 -p 19506:8086 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/pict\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" pict-image:local","docker-dev-shell":"docker exec -it pict-dev /bin/bash","lint":"eslint source/**/*.js test/**/*.js","types":"tsc -p ."},"files":["source/","dist/","types/"],"types":"types/source/Pict.d.ts","mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"repository":{"type":"git","url":"git+https://stevenvelozo@github.com/stevenvelozo/pict.git"},"author":"steven velozo <steven@velozo.com>","license":"MIT","bugs":{"url":"https://github.com/fable-retold/pict/issues"},"homepage":"https://github.com/fable-retold/pict#readme","devDependencies":{"@eslint/js":"^9.39.1","@types/jquery":"^3.5.33","@types/sinon":"^17.0.4","eslint":"^9.39.1","globals":"^16.5.0","pict-docuserve":"^1.4.19","quackage":"^1.3.0","sinon":"^20.0.0","typescript":"^5.9.3"},"dependencies":{"cachetrax":"^1.0.6","fable":"^3.1.78","pict-application":"^1.0.34","pict-provider":"^1.0.13","pict-template":"^1.0.15","pict-view":"^1.0.68"}};},{}],193:[function(require,module,exports){// This assumes Pict has been required in the browser. Delcare these as globals so linter can do its job.
|
|
6222
6222
|
/* global Pict, _Pict: writeable *//**
|
|
6223
6223
|
* Simple function to load a pict Application
|
|
6224
6224
|
*
|
|
@@ -6506,6 +6506,19 @@ for(let i=0;i<3;i++){const tmpHave=isNaN(tmpParts[i])?0:tmpParts[i];const tmpNee
|
|
|
6506
6506
|
* @return {void}
|
|
6507
6507
|
*/resolveEntityQuerySupport(pEntity,pURLPrefix,fCallback){if(!this.useQueryEndpoint){return fCallback(null,false);}const tmpKey=this._capabilityKey(pEntity,pURLPrefix);if(tmpKey in this.endpointCapabilityCache){return fCallback(null,this.endpointCapabilityCache[tmpKey].SupportsQuery);}if(this.endpointCapabilityInflight[tmpKey]){this.endpointCapabilityInflight[tmpKey].push(fCallback);return;}this.endpointCapabilityInflight[tmpKey]=[fCallback];/** @type {Record<string, any>} */let tmpOptions={url:`${pURLPrefix||this.options.urlPrefix}${pEntity}/Schema`};tmpOptions=this.prepareRequestOptions(tmpOptions);this.restClient.getJSON(tmpOptions,(pError,pResponse,pBody)=>{let tmpSupportsQuery=false;if(!pError){try{tmpSupportsQuery=this.evaluateQueryEndpointSupport(pBody);}catch(pEvaluateError){tmpSupportsQuery=false;}// Only cache on a clean probe; transient errors stay re-probeable.
|
|
6508
6508
|
this.endpointCapabilityCache[tmpKey]={SupportsQuery:tmpSupportsQuery,Metadata:pBody&&pBody.RetoldMetadata||null};}else{this.log.warn(`EntityProvider capability probe for [${pEntity}] failed; falling back to GET reads: ${pError}`);}const tmpCallbacks=this.endpointCapabilityInflight[tmpKey];delete this.endpointCapabilityInflight[tmpKey];for(let i=0;i<tmpCallbacks.length;i++){tmpCallbacks[i](null,tmpSupportsQuery);}});}/**
|
|
6509
|
+
* Decode a meadow filter expression for transport in a POST /:Entity/Query
|
|
6510
|
+
* body. Filter values are built URL-encoded for the legacy GET reads (e.g.
|
|
6511
|
+
* `%25...%25` for LIKE wildcards, encodeURIComponent'd distinct values),
|
|
6512
|
+
* relying on the server URL-decoding the `:Filter` path segment of the GET
|
|
6513
|
+
* route. The POST /Query route copies the body's Filter onto pRequest.params
|
|
6514
|
+
* verbatim with no decode, so the encoding must be undone here to deliver the
|
|
6515
|
+
* same value the GET path did. Malformed percent-sequences (a pre-existing
|
|
6516
|
+
* GET-path hazard) fall back to the raw string so the POST path never fails
|
|
6517
|
+
* where GET would not.
|
|
6518
|
+
*
|
|
6519
|
+
* @param {string} pMeadowFilterExpression - The (URL-encoded) meadow filter string.
|
|
6520
|
+
* @return {string} The decoded filter string.
|
|
6521
|
+
*/_decodeFilterForQueryBody(pMeadowFilterExpression){try{return decodeURIComponent(pMeadowFilterExpression);}catch(pDecodeError){this.log.warn(`EntityProvider could not URL-decode filter [${pMeadowFilterExpression}] for POST /Query body; sending raw: ${pDecodeError}`);return pMeadowFilterExpression;}}/**
|
|
6509
6522
|
* Build the POST /:Entity/Query request body for a filtered read.
|
|
6510
6523
|
*
|
|
6511
6524
|
* @param {string} pMeadowFilterExpression - The meadow filter string (may be empty).
|
|
@@ -6513,7 +6526,7 @@ this.endpointCapabilityCache[tmpKey]={SupportsQuery:tmpSupportsQuery,Metadata:pB
|
|
|
6513
6526
|
* @param {number|null} [pCap] - Pagination page size.
|
|
6514
6527
|
* @param {Record<string, any>} [pProjection] - Optional { Mode:'LiteExtended', ExtraColumns:[...] }.
|
|
6515
6528
|
* @return {Record<string, any>} The request body envelope.
|
|
6516
|
-
*/_buildQueryReadBody(pMeadowFilterExpression,pBegin,pCap,pProjection){/** @type {Record<string, any>} */const tmpBody={};if(pMeadowFilterExpression){tmpBody.Filter=pMeadowFilterExpression;}if(typeof pBegin==='number'){tmpBody.Begin=pBegin;}if(typeof pCap==='number'){tmpBody.Cap=pCap;}if(pProjection&&pProjection.Mode==='LiteExtended'&&Array.isArray(pProjection.ExtraColumns)&&pProjection.ExtraColumns.length>0){// LiteExtended GET maps to a Lite read carrying ExtraColumns on Query.
|
|
6529
|
+
*/_buildQueryReadBody(pMeadowFilterExpression,pBegin,pCap,pProjection){/** @type {Record<string, any>} */const tmpBody={};if(pMeadowFilterExpression){tmpBody.Filter=this._decodeFilterForQueryBody(pMeadowFilterExpression);}if(typeof pBegin==='number'){tmpBody.Begin=pBegin;}if(typeof pCap==='number'){tmpBody.Cap=pCap;}if(pProjection&&pProjection.Mode==='LiteExtended'&&Array.isArray(pProjection.ExtraColumns)&&pProjection.ExtraColumns.length>0){// LiteExtended GET maps to a Lite read carrying ExtraColumns on Query.
|
|
6517
6530
|
tmpBody.Lite=true;tmpBody.ExtraColumns=pProjection.ExtraColumns.join(',');}return tmpBody;}/**
|
|
6518
6531
|
* Read a page of an entity set, using POST /:Entity/Query when supported and
|
|
6519
6532
|
* falling back to the legacy GET read otherwise. The callback mirrors
|
|
@@ -6853,7 +6866,11 @@ else if(tmpColumnName in this.entityColumnTranslations){tmpIDColumnsToCache.push
|
|
|
6853
6866
|
this.resolveEntityQuerySupport(pEntity,tmpURLPrefix,(pSupportError,pSupportsQuery)=>{const tmpReadOptions={SupportsQuery:pSupportsQuery,URLPrefix:tmpURLPrefix,Postfix:postfix||''};// Discard anything from the cache that has expired or is over size.
|
|
6854
6867
|
this.recordSetCache[tmpCacheKey].prune(function(){let tmpPossibleRecords=this.recordSetCache[tmpCacheKey].read(pMeadowFilterExpression);if(tmpPossibleRecords){return fCallback(null,tmpPossibleRecords);}if(pOptions.NoCount){// Lazily load until we hit a not full page rather than using couns.
|
|
6855
6868
|
// Does not respect parallelization.
|
|
6856
|
-
const pageSize=250;let page=0;let returnSet=[];const recursiveCallback=(pDownloadError,pDownloadResponse,pDownloadBody)=>{
|
|
6869
|
+
const pageSize=250;let page=0;let returnSet=[];const recursiveCallback=(pDownloadError,pDownloadResponse,pDownloadBody)=>{// A transport-level failure (e.g. connection reset, expired TLS
|
|
6870
|
+
// cert) calls back with no response, so guard every pDownloadResponse
|
|
6871
|
+
// deref and surface the underlying error rather than throwing a
|
|
6872
|
+
// TypeError on the missing statusCode.
|
|
6873
|
+
if(pDownloadError||pDownloadResponse&&pDownloadResponse.statusCode&&pDownloadResponse.statusCode>=400||!Array.isArray(pDownloadBody)){const tmpStatusCode=pDownloadResponse?pDownloadResponse.statusCode:'no response';const tmpStatusDetail=pDownloadError?pDownloadError.message||pDownloadError:pDownloadResponse?pDownloadResponse.statusMessage:'';this.log.error(`Error getting entity set of [${pEntity}] filtered to [${pMeadowFilterExpression}]: ${tmpStatusCode} ${tmpStatusDetail}`);return fCallback(pDownloadError||new Error(`Error getting entity set of [${pEntity}] filtered to [${pMeadowFilterExpression}]: ${tmpStatusCode} ${JSON.stringify(pDownloadBody||{})}`),[]);}returnSet=returnSet.concat(pDownloadBody);if((pDownloadBody===null||pDownloadBody===void 0?void 0:pDownloadBody.length)<pageSize){this.recordSetCache[tmpCacheKey].put(returnSet,pMeadowFilterExpression);this.cacheIndividualEntityRecords(pEntity,returnSet,tmpScope);fCallback(null,returnSet);}else{page+=1;this._readEntityPage(pEntity,pMeadowFilterExpression,page*pageSize,pageSize,tmpReadOptions,recursiveCallback);}};return this._readEntityPage(pEntity,pMeadowFilterExpression,page*pageSize,pageSize,tmpReadOptions,recursiveCallback);}return this.getEntitySetRecordCount(pEntity,pMeadowFilterExpression,(pRecordCountError,pRecordCount)=>{if(pRecordCountError){return fCallback(pRecordCountError);}let tmpRecordCount=pRecordCount;if(isNaN(pRecordCount)){this.log.error(`Entity count did not return a number for [${pEntity}] filtered to [${pMeadowFilterExpression}]... something is fatally wrong from the server accessed in getEntitySet call.`);return fCallback(new Error('Entity count did not return a number in getEntitySet.'));}let tmpDownloadBatchSize=this.options.downloadBatchSize;const tmpPageCount=Math.ceil(tmpRecordCount/tmpDownloadBatchSize);// Build an indexed array of page descriptors to preserve ordering
|
|
6857
6874
|
const tmpPages=[];for(let i=0;i<tmpPageCount;i++){tmpPages.push({Index:i,Begin:i*tmpDownloadBatchSize,Records:null});}// Fetch pages concurrently and reassemble in order.
|
|
6858
6875
|
// Per-call DownloadPageConcurrency overrides the provider-level default.
|
|
6859
6876
|
const tmpPageConcurrency=typeof pOptions.DownloadPageConcurrency==='number'?pOptions.DownloadPageConcurrency:typeof this.options.downloadPageConcurrency==='number'?this.options.downloadPageConcurrency:4;this.fable.Utility.eachLimit(tmpPages,tmpPageConcurrency,(pPage,fDownloadCallback)=>{this._readEntityPage(pEntity,pMeadowFilterExpression,pPage.Begin,tmpDownloadBatchSize,tmpReadOptions,(pDownloadError,pDownloadResponse,pDownloadBody)=>{if(pDownloadResponse&&pDownloadResponse.statusCode&&pDownloadResponse.statusCode>=400){this.log.error(`Error getting entity set of [${pEntity}] filtered to [${pMeadowFilterExpression}] [${pPage.Begin}/${tmpDownloadBatchSize}]: ${pDownloadResponse.statusCode} ${pDownloadResponse.statusMessage}`);return fDownloadCallback(new Error(`Error getting entity set of [${pEntity}] filtered to [${pMeadowFilterExpression}] [${pPage.Begin}/${tmpDownloadBatchSize}]: ${pDownloadResponse.statusCode} ${JSON.stringify(pDownloadBody||{})}`));}if(Array.isArray(pDownloadBody)){pPage.Records=pDownloadBody;}return fDownloadCallback(pDownloadError);});},pFullDownloadError=>{// Reassemble pages in index order to maintain consistent ordering
|