solid-logic 6.0.0-0 → 6.0.0-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.
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../util/ns.cjs.js"),t=require("../acl/aclLogic.cjs.js"),n=require("./resourceHttp.cjs.js"),r=require("./resourceMetadata.cjs.js");let i=require("rdflib");function a(a,o,s,c){function l(e){return s.createContainer(e)}function u(e){return s.isContainer(e)}function d(e){return s.getContainerMemberCount(e)}function f(n,i){let o,s=!1,c=!1,l,u;if(i.headers){o=i.headers.get(`content-type`)?.split(`;`)[0]??void 0;let t=r.readWacAccessInfo(i.headers.get(`wac-allow`));s=t.canEdit,c=t.isPublic,l=i.headers.get(`etag`)??void 0,u=a.anyValue(n,e.ns.dct(`modified`))||a.anyValue(n,e.ns.dc(`modified`))||void 0}(!i.headers||!i.headers.get(`content-type`))&&(!i.headers||!i.headers.get(`wac-allow`)||!i.headers.get(`etag`))&&a.each(null,a.sym(`http://www.w3.org/2007/ont/link#requestedURI`),n).map(t=>{let i=a.any(t,a.sym(`http://www.w3.org/2007/ont/link#response`));if(i&&i.termType===`NamedNode`){let t=a.anyValue(i,e.ns.httph(`content-type`))||void 0;o===void 0&&(o=t);let d=r.readWacAccessInfo(a.anyValue(i,e.ns.httph(`wac-allow`))||a.anyValue(i,e.ns.httph(`WAC-Allow`)));s||=d.canEdit,c||=d.isPublic;let f=a.anyValue(i,e.ns.httph(`etag`))||void 0;l===void 0&&(l=f),u=a.anyValue(n,e.ns.dct(`modified`))||a.anyValue(n,e.ns.dc(`modified`))||void 0}});let d=a.any(n,t.ACL_LINK)?.value||void 0;return{contentType:o,access:{canEdit:s,isPublic:c},aclUri:d,eTag:l,modified:u}}async function p(e){let t=await a.fetcher.webOperation(`HEAD`,e.uri);return n.assertSuccessfulHttpResponse(t,`HEAD`),f(e,t)}async function m(t){let n=a.any(t,e.ns.ldp(`contains`))||t.dir();if(!n||n.termType!==`NamedNode`)return!1;try{return(await p(n)).access.canEdit}catch{return!1}}async function h(e){return m(e)}async function g(e){return p(e)}async function _(e){let t;try{t=await p(e)}catch{t={contentType:void 0,access:{canEdit:!1,isPublic:!1},aclUri:void 0,eTag:void 0,modified:void 0}}let n=await h(e),r={canEdit:t.access?.canEdit??!1,isPublic:t.access?.isPublic??!1,canDelete:n};return{...t,access:r}}async function v(e,t){if(t)try{await c.deleteTypeIndexRegistrationForResource(e,t)}catch{}}async function y(t,r={}){let o=t.dir();if(u(t)){let e=await s.getContainerMembers(t);await Promise.all(e.map(e=>y((0,i.sym)(e),r)))}let c;try{c=await a.fetcher._fetch(t.value,{method:`DELETE`}),n.assertSuccessfulHttpResponse(c,`DELETE`,{allowNotFound:!0})}catch(e){if(!n.isMissingError(e))throw e}return r.deleteTypeIndexes&&await v(t,r.user),o&&a.removeMatches(o,e.ns.ldp(`contains`),t,o.doc()),a.removeDocument(t),a.fetcher.unload(t.doc()),c}async function b(e,t){await y(e,{deleteTypeIndexes:!0,user:t})}return{recursiveDelete:y,deleteResourceAndTypeIndexIfExists:b,fetchMetadata:g,fetchMetadataWithDelete:_,createContainer:l,isContainer:u,getContainerMemberCount:d}}exports.createResourceLogic=a;
|
|
1
|
+
const e=require("../util/ns.cjs.js"),t=require("../acl/aclLogic.cjs.js"),n=require("./resourceHttp.cjs.js"),r=require("./resourceMetadata.cjs.js");let i=require("rdflib");function a(a,o,s,c){function l(e){return s.createContainer(e)}function u(e){return s.isContainer(e)}function d(e){return s.getContainerMemberCount(e)}function f(n,i){let o,s=!1,c=!1,l,u;if(i.headers){o=i.headers.get(`content-type`)?.split(`;`)[0]??void 0;let t=r.readWacAccessInfo(i.headers.get(`wac-allow`));s=t.canEdit,c=t.isPublic,l=i.headers.get(`etag`)??void 0,u=a.anyValue(n,e.ns.dct(`modified`))||a.anyValue(n,e.ns.dc(`modified`))||void 0}(!i.headers||!i.headers.get(`content-type`))&&(!i.headers||!i.headers.get(`wac-allow`)||!i.headers.get(`etag`))&&a.each(null,a.sym(`http://www.w3.org/2007/ont/link#requestedURI`),n).map(t=>{let i=a.any(t,a.sym(`http://www.w3.org/2007/ont/link#response`));if(i&&i.termType===`NamedNode`){let t=a.anyValue(i,e.ns.httph(`content-type`))||void 0;o===void 0&&(o=t);let d=r.readWacAccessInfo(a.anyValue(i,e.ns.httph(`wac-allow`))||a.anyValue(i,e.ns.httph(`WAC-Allow`)));s||=d.canEdit,c||=d.isPublic;let f=a.anyValue(i,e.ns.httph(`etag`))||void 0;l===void 0&&(l=f),u=a.anyValue(n,e.ns.dct(`modified`))||a.anyValue(n,e.ns.dc(`modified`))||void 0}});let d=a.any(n,t.ACL_LINK)?.value||void 0;return{contentType:o,access:{canEdit:s,isPublic:c},aclUri:d,eTag:l,modified:u}}async function p(e){let t=await a.fetcher.webOperation(`HEAD`,e.uri);return n.assertSuccessfulHttpResponse(t,`HEAD`),f(e,t)}async function m(t){let n=a.any(t,e.ns.ldp(`contains`))||t.dir();if(!n||n.termType!==`NamedNode`)return!1;try{return(await p(n)).access.canEdit}catch{return!1}}async function h(e){return m(e)}async function g(e){return p(e)}async function _(e){let t;try{t=await p(e)}catch{t={contentType:void 0,access:{canEdit:!1,isPublic:!1},aclUri:void 0,eTag:void 0,modified:void 0}}let n=await h(e),r={canEdit:t.access?.canEdit??!1,isPublic:t.access?.isPublic??!1,canDelete:n};return{...t,access:r}}async function v(e,t){if(t)try{await c.deleteTypeIndexRegistrationForResource(e,t)}catch{}}async function y(t,r={}){let o=t.dir();if(u(t)){let e=await s.getContainerMembers(t);await Promise.all(e.map(e=>y((0,i.sym)(e),r)))}let c;try{c=await a.fetcher._fetch(t.value,{method:`DELETE`}),n.assertSuccessfulHttpResponse(c,`DELETE`,{allowNotFound:!0})}catch(e){if(!n.isMissingError(e))throw e}return r.deleteTypeIndexes&&await v(t,r.user),o&&a.removeMatches(o,e.ns.ldp(`contains`),t,o.doc()),a.removeDocument(t),a.fetcher.unload(t.doc()),c}async function b(e,t){await y(e,{deleteTypeIndexes:!0,user:t})}async function x(e){if(!e||!a.updater||!a.fetcher||typeof a.fetcher.refresh!=`function`)return!1;let t=e.uri||e.value||``;if(!t)return!1;let n=a.updater.editable(t,a);if(n!==!1&&n!==void 0)return!0;try{await a.fetcher.refresh(e)}catch(e){throw e instanceof Error?e:Error(`Failed to refresh <${t}>`)}let r=a.updater.editable(t,a);return r!==!1&&r!==void 0}return{recursiveDelete:y,deleteResourceAndTypeIndexIfExists:b,fetchMetadata:g,fetchMetadataWithDelete:_,checkAndRefreshEditable:x,createContainer:l,isContainer:u,getContainerMemberCount:d}}exports.createResourceLogic=a;
|
|
2
2
|
//# sourceMappingURL=resourceLogic.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resourceLogic.cjs.js","names":[],"sources":["../../src/resource/resourceLogic.ts"],"sourcesContent":["import { NamedNode, sym } from 'rdflib'\nimport { ACL_LINK } from '../acl/aclLogic'\nimport { ns } from '../util/ns'\nimport { assertSuccessfulHttpResponse, isMissingError } from './resourceHttp'\nimport { readWacAccessInfo } from './resourceMetadata'\nimport { type AclLogic, type ResourceAccess, type ResourceAccessWithDelete, type ResourceDeleteOptions, type ResourceLogic, type ResourceMetadata, type ResourceMetadataWithDelete, type TypeIndexLogic } from '../types'\n\nexport function createResourceLogic(store, aclLogic: AclLogic, containerLogic, typeIndexLogic: TypeIndexLogic): ResourceLogic {\n function createContainer(url: string) {\n return containerLogic.createContainer(url)\n }\n\n function isContainer(resourceNode: NamedNode) {\n return containerLogic.isContainer(resourceNode)\n }\n\n function getContainerMemberCount(resourceNode: NamedNode) {\n return containerLogic.getContainerMemberCount(resourceNode)\n }\n\n function readMetadata(subject: NamedNode, response: Response): ResourceMetadata {\n let contentType: string | undefined\n let canEdit = false\n let isPublic = false\n let eTag: string | undefined\n let modified: string | undefined\n\n if (response.headers) {\n const contentTypeHeader = response.headers.get('content-type')\n contentType = contentTypeHeader?.split(';')[0] ?? undefined\n\n const accessFlags = readWacAccessInfo(response.headers.get('wac-allow'))\n canEdit = accessFlags.canEdit\n isPublic = accessFlags.isPublic\n eTag = response.headers.get('etag') ?? undefined\n modified = store.anyValue(subject as any, ns.dct('modified')) || store.anyValue(subject as any, ns.dc('modified')) || undefined\n }\n\n if ((!response.headers || !response.headers.get('content-type')) && (!response.headers || !response.headers.get('wac-allow') || !response.headers.get('etag'))) {\n const reqs = store.each(\n null,\n store.sym('http://www.w3.org/2007/ont/link#requestedURI'),\n subject\n )\n reqs.map((req: any) => {\n const responseNode = store.any(\n req as any,\n store.sym('http://www.w3.org/2007/ont/link#response')\n )\n if (responseNode && responseNode.termType === 'NamedNode') {\n const responseContentType = store.anyValue(responseNode as any, ns.httph('content-type')) || undefined\n if (contentType === undefined) {\n contentType = responseContentType\n }\n const wacAllow = (store.anyValue(responseNode as any, ns.httph('wac-allow')) as string | undefined) ||\n (store.anyValue(responseNode as any, ns.httph('WAC-Allow')) as string | undefined)\n const accessFlags = readWacAccessInfo(wacAllow)\n canEdit = canEdit || accessFlags.canEdit\n isPublic = isPublic || accessFlags.isPublic\n const responseETag = store.anyValue(responseNode as any, ns.httph('etag')) || undefined\n if (eTag === undefined) {\n eTag = responseETag\n }\n modified = store.anyValue(subject as any, ns.dct('modified')) || store.anyValue(subject as any, ns.dc('modified')) || undefined\n }\n })\n }\n\n const aclUri = store.any(subject, ACL_LINK)?.value || undefined\n const access: ResourceAccess = { canEdit, isPublic }\n return { contentType, access, aclUri, eTag, modified }\n }\n\n async function fetchHeadMetadata(subject: NamedNode): Promise<ResourceMetadata> {\n const response = await store.fetcher.webOperation('HEAD', subject.uri)\n assertSuccessfulHttpResponse(response, 'HEAD')\n return readMetadata(subject, response)\n }\n\n async function userCanWriteToContainingContainer(resourceNode: NamedNode): Promise<boolean> {\n const containerNode = store.any(resourceNode, ns.ldp('contains')) || resourceNode.dir()\n if (!containerNode || containerNode.termType !== 'NamedNode') {\n return false\n }\n\n try {\n const containerMetadata = await fetchHeadMetadata(containerNode as NamedNode)\n return containerMetadata.access.canEdit\n } catch (_error) {\n return false\n }\n }\n\n async function userCanDeleteResource(resourceNode: NamedNode): Promise<boolean> {\n return userCanWriteToContainingContainer(resourceNode)\n }\n\n async function fetchMetadata(subject: NamedNode): Promise<ResourceMetadata> {\n return fetchHeadMetadata(subject)\n }\n\n async function fetchMetadataWithDelete(subject: NamedNode): Promise<ResourceMetadataWithDelete> {\n let resourceMetadata: ResourceMetadata\n\n try {\n resourceMetadata = await fetchHeadMetadata(subject)\n } catch (_error) {\n resourceMetadata = {\n contentType: undefined,\n access: { canEdit: false, isPublic: false },\n aclUri: undefined,\n eTag: undefined,\n modified: undefined\n }\n }\n\n const canDelete = await userCanDeleteResource(subject)\n const access: ResourceAccessWithDelete = {\n canEdit: resourceMetadata.access?.canEdit ?? false,\n isPublic: resourceMetadata.access?.isPublic ?? false,\n canDelete\n }\n return { ...resourceMetadata, access }\n }\n\n async function deleteTypeIndexesForResource(resourceNode: NamedNode, user?: NamedNode | null) {\n if (!user) return\n\n try {\n await typeIndexLogic.deleteTypeIndexRegistrationForResource(resourceNode, user)\n } catch (_error) {\n // Keep resource deletion best-effort even if type-index cleanup fails.\n }\n }\n\n async function recursiveDelete(resourceNode: NamedNode, options: ResourceDeleteOptions = {}) {\n const resourceParent = resourceNode.dir()\n\n if (isContainer(resourceNode)) {\n const containerMembers = await containerLogic.getContainerMembers(resourceNode)\n await Promise.all(containerMembers.map((url) => recursiveDelete(sym(url), options)))\n }\n\n let deleted\n try {\n deleted = await store.fetcher._fetch(resourceNode.value, { method: 'DELETE' })\n assertSuccessfulHttpResponse(deleted, 'DELETE', { allowNotFound: true })\n } catch (error) {\n if (!isMissingError(error)) {\n throw error\n }\n }\n\n if (options.deleteTypeIndexes) {\n await deleteTypeIndexesForResource(resourceNode, options.user)\n }\n\n if (resourceParent) {\n store.removeMatches(resourceParent, ns.ldp('contains'), resourceNode, resourceParent.doc())\n }\n\n store.removeDocument(resourceNode)\n store.fetcher.unload(resourceNode.doc())\n return deleted\n }\n\n async function deleteResourceAndTypeIndexIfExists(resourceNode: NamedNode, user?: NamedNode | null) {\n await recursiveDelete(resourceNode, { deleteTypeIndexes: true, user })\n }\n\n return {\n recursiveDelete,\n deleteResourceAndTypeIndexIfExists,\n fetchMetadata,\n fetchMetadataWithDelete,\n createContainer,\n isContainer,\n getContainerMemberCount\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resourceLogic.cjs.js","names":[],"sources":["../../src/resource/resourceLogic.ts"],"sourcesContent":["import { NamedNode, sym, LiveStore } from 'rdflib'\nimport { ACL_LINK } from '../acl/aclLogic'\nimport { ns } from '../util/ns'\nimport { assertSuccessfulHttpResponse, isMissingError } from './resourceHttp'\nimport { readWacAccessInfo } from './resourceMetadata'\nimport { type AclLogic, type ResourceAccess, type ResourceAccessWithDelete, type ResourceDeleteOptions, type ResourceLogic, type ResourceMetadata, type ResourceMetadataWithDelete, type TypeIndexLogic } from '../types'\n\nexport function createResourceLogic(store: LiveStore, aclLogic: AclLogic, containerLogic, typeIndexLogic: TypeIndexLogic): ResourceLogic {\n function createContainer(url: string) {\n return containerLogic.createContainer(url)\n }\n\n function isContainer(resourceNode: NamedNode) {\n return containerLogic.isContainer(resourceNode)\n }\n\n function getContainerMemberCount(resourceNode: NamedNode) {\n return containerLogic.getContainerMemberCount(resourceNode)\n }\n\n function readMetadata(subject: NamedNode, response: Response): ResourceMetadata {\n let contentType: string | undefined\n let canEdit = false\n let isPublic = false\n let eTag: string | undefined\n let modified: string | undefined\n\n if (response.headers) {\n const contentTypeHeader = response.headers.get('content-type')\n contentType = contentTypeHeader?.split(';')[0] ?? undefined\n\n const accessFlags = readWacAccessInfo(response.headers.get('wac-allow'))\n canEdit = accessFlags.canEdit\n isPublic = accessFlags.isPublic\n eTag = response.headers.get('etag') ?? undefined\n modified = store.anyValue(subject as any, ns.dct('modified')) || store.anyValue(subject as any, ns.dc('modified')) || undefined\n }\n\n if ((!response.headers || !response.headers.get('content-type')) && (!response.headers || !response.headers.get('wac-allow') || !response.headers.get('etag'))) {\n const reqs = store.each(\n null,\n store.sym('http://www.w3.org/2007/ont/link#requestedURI'),\n subject\n )\n reqs.map((req: any) => {\n const responseNode = store.any(\n req as any,\n store.sym('http://www.w3.org/2007/ont/link#response')\n )\n if (responseNode && responseNode.termType === 'NamedNode') {\n const responseContentType = store.anyValue(responseNode as any, ns.httph('content-type')) || undefined\n if (contentType === undefined) {\n contentType = responseContentType\n }\n const wacAllow = (store.anyValue(responseNode as any, ns.httph('wac-allow')) as string | undefined) ||\n (store.anyValue(responseNode as any, ns.httph('WAC-Allow')) as string | undefined)\n const accessFlags = readWacAccessInfo(wacAllow)\n canEdit = canEdit || accessFlags.canEdit\n isPublic = isPublic || accessFlags.isPublic\n const responseETag = store.anyValue(responseNode as any, ns.httph('etag')) || undefined\n if (eTag === undefined) {\n eTag = responseETag\n }\n modified = store.anyValue(subject as any, ns.dct('modified')) || store.anyValue(subject as any, ns.dc('modified')) || undefined\n }\n })\n }\n\n const aclUri = store.any(subject, ACL_LINK)?.value || undefined\n const access: ResourceAccess = { canEdit, isPublic }\n return { contentType, access, aclUri, eTag, modified }\n }\n\n async function fetchHeadMetadata(subject: NamedNode): Promise<ResourceMetadata> {\n const response = await store.fetcher.webOperation('HEAD', subject.uri)\n assertSuccessfulHttpResponse(response, 'HEAD')\n return readMetadata(subject, response)\n }\n\n async function userCanWriteToContainingContainer(resourceNode: NamedNode): Promise<boolean> {\n const containerNode = store.any(resourceNode, ns.ldp('contains')) || resourceNode.dir()\n if (!containerNode || containerNode.termType !== 'NamedNode') {\n return false\n }\n\n try {\n const containerMetadata = await fetchHeadMetadata(containerNode as NamedNode)\n return containerMetadata.access.canEdit\n } catch (_error) {\n return false\n }\n }\n\n async function userCanDeleteResource(resourceNode: NamedNode): Promise<boolean> {\n return userCanWriteToContainingContainer(resourceNode)\n }\n\n async function fetchMetadata(subject: NamedNode): Promise<ResourceMetadata> {\n return fetchHeadMetadata(subject)\n }\n\n async function fetchMetadataWithDelete(subject: NamedNode): Promise<ResourceMetadataWithDelete> {\n let resourceMetadata: ResourceMetadata\n\n try {\n resourceMetadata = await fetchHeadMetadata(subject)\n } catch (_error) {\n resourceMetadata = {\n contentType: undefined,\n access: { canEdit: false, isPublic: false },\n aclUri: undefined,\n eTag: undefined,\n modified: undefined\n }\n }\n\n const canDelete = await userCanDeleteResource(subject)\n const access: ResourceAccessWithDelete = {\n canEdit: resourceMetadata.access?.canEdit ?? false,\n isPublic: resourceMetadata.access?.isPublic ?? false,\n canDelete\n }\n return { ...resourceMetadata, access }\n }\n\n async function deleteTypeIndexesForResource(resourceNode: NamedNode, user?: NamedNode | null) {\n if (!user) return\n\n try {\n await typeIndexLogic.deleteTypeIndexRegistrationForResource(resourceNode, user)\n } catch (_error) {\n // Keep resource deletion best-effort even if type-index cleanup fails.\n }\n }\n\n async function recursiveDelete(resourceNode: NamedNode, options: ResourceDeleteOptions = {}) {\n const resourceParent = resourceNode.dir()\n\n if (isContainer(resourceNode)) {\n const containerMembers = await containerLogic.getContainerMembers(resourceNode)\n await Promise.all(containerMembers.map((url) => recursiveDelete(sym(url), options)))\n }\n\n let deleted\n try {\n deleted = await store.fetcher._fetch(resourceNode.value, { method: 'DELETE' })\n assertSuccessfulHttpResponse(deleted, 'DELETE', { allowNotFound: true })\n } catch (error) {\n if (!isMissingError(error)) {\n throw error\n }\n }\n\n if (options.deleteTypeIndexes) {\n await deleteTypeIndexesForResource(resourceNode, options.user)\n }\n\n if (resourceParent) {\n store.removeMatches(resourceParent, ns.ldp('contains'), resourceNode, resourceParent.doc())\n }\n\n store.removeDocument(resourceNode)\n store.fetcher.unload(resourceNode.doc())\n return deleted\n }\n\n async function deleteResourceAndTypeIndexIfExists(resourceNode: NamedNode, user?: NamedNode | null) {\n await recursiveDelete(resourceNode, { deleteTypeIndexes: true, user })\n }\n\n async function checkAndRefreshEditable(resourceNode: NamedNode | null | undefined): Promise<boolean> {\n if (!resourceNode || !store.updater || !store.fetcher || typeof store.fetcher.refresh !== 'function') return false\n\n const resourceUri = resourceNode.uri || resourceNode.value || ''\n if (!resourceUri) return false\n\n const editable = store.updater.editable(resourceUri, store)\n if (editable !== false && editable !== undefined) {\n return true\n }\n\n try {\n await store.fetcher.refresh(resourceNode)\n } catch (error) {\n throw error instanceof Error ? error : new Error(`Failed to refresh <${resourceUri}>`)\n }\n\n const editableAfterRefresh = store.updater.editable(resourceUri, store)\n return editableAfterRefresh !== false && editableAfterRefresh !== undefined\n }\n\n return {\n recursiveDelete,\n deleteResourceAndTypeIndexIfExists,\n fetchMetadata,\n fetchMetadataWithDelete,\n checkAndRefreshEditable,\n createContainer,\n isContainer,\n getContainerMemberCount\n }\n}\n"],"mappings":"2KAOA,SAAgB,EAAoB,EAAkB,EAAoB,EAAgB,EAA+C,CACvI,SAAS,EAAgB,EAAa,CACpC,OAAO,EAAe,gBAAgB,CAAG,CAC3C,CAEA,SAAS,EAAY,EAAyB,CAC5C,OAAO,EAAe,YAAY,CAAY,CAChD,CAEA,SAAS,EAAwB,EAAyB,CACxD,OAAO,EAAe,wBAAwB,CAAY,CAC5D,CAEA,SAAS,EAAa,EAAoB,EAAsC,CAC9E,IAAI,EACA,EAAU,GACV,EAAW,GACX,EACA,EAEJ,GAAI,EAAS,QAAS,CAEpB,EAD0B,EAAS,QAAQ,IAAI,cACjC,CAAA,EAAmB,MAAM,GAAG,CAAC,CAAC,IAAM,IAAA,GAElD,IAAM,EAAc,EAAA,kBAAkB,EAAS,QAAQ,IAAI,WAAW,CAAC,EACvE,EAAU,EAAY,QACtB,EAAW,EAAY,SACvB,EAAO,EAAS,QAAQ,IAAI,MAAM,GAAK,IAAA,GACvC,EAAW,EAAM,SAAS,EAAgB,EAAA,GAAG,IAAI,UAAU,CAAC,GAAK,EAAM,SAAS,EAAgB,EAAA,GAAG,GAAG,UAAU,CAAC,GAAK,IAAA,EACxH,EAEK,CAAC,EAAS,SAAW,CAAC,EAAS,QAAQ,IAAI,cAAc,KAAO,CAAC,EAAS,SAAW,CAAC,EAAS,QAAQ,IAAI,WAAW,GAAK,CAAC,EAAS,QAAQ,IAAI,MAAM,IAM1J,EALmB,KACjB,KACA,EAAM,IAAI,8CAA8C,EACxD,CAEF,CAAA,CAAK,IAAK,GAAa,CACrB,IAAM,EAAe,EAAM,IACzB,EACA,EAAM,IAAI,0CAA0C,CACtD,EACA,GAAI,GAAgB,EAAa,WAAa,YAAa,CACzD,IAAM,EAAsB,EAAM,SAAS,EAAqB,EAAA,GAAG,MAAM,cAAc,CAAC,GAAK,IAAA,GACzF,IAAgB,IAAA,KAClB,EAAc,GAIhB,IAAM,EAAc,EAAA,kBAFF,EAAM,SAAS,EAAqB,EAAA,GAAG,MAAM,WAAW,CAAC,GACxE,EAAM,SAAS,EAAqB,EAAA,GAAG,MAAM,WAAW,CAAC,CACd,EAC9C,IAAqB,EAAY,QACjC,IAAuB,EAAY,SACnC,IAAM,EAAe,EAAM,SAAS,EAAqB,EAAA,GAAG,MAAM,MAAM,CAAC,GAAK,IAAA,GAC1E,IAAS,IAAA,KACX,EAAO,GAET,EAAW,EAAM,SAAS,EAAgB,EAAA,GAAG,IAAI,UAAU,CAAC,GAAK,EAAM,SAAS,EAAgB,EAAA,GAAG,GAAG,UAAU,CAAC,GAAK,IAAA,EACxH,CACF,CAAC,EAGH,IAAM,EAAS,EAAM,IAAI,EAAS,EAAA,QAAQ,CAAC,EAAE,OAAS,IAAA,GAEtD,MAAO,CAAE,cAAa,OAAA,CADW,UAAS,UACpB,EAAQ,SAAQ,OAAM,UAAS,CACvD,CAEA,eAAe,EAAkB,EAA+C,CAC9E,IAAM,EAAW,MAAM,EAAM,QAAQ,aAAa,OAAQ,EAAQ,GAAG,EAErE,OADA,EAAA,6BAA6B,EAAU,MAAM,EACtC,EAAa,EAAS,CAAQ,CACvC,CAEA,eAAe,EAAkC,EAA2C,CAC1F,IAAM,EAAgB,EAAM,IAAI,EAAc,EAAA,GAAG,IAAI,UAAU,CAAC,GAAK,EAAa,IAAI,EACtF,GAAI,CAAC,GAAiB,EAAc,WAAa,YAC/C,MAAO,GAGT,GAAI,CAEF,OAAO,MADyB,EAAkB,CAA0B,EAAA,CACnD,OAAO,OAClC,MAAiB,CACf,MAAO,EACT,CACF,CAEA,eAAe,EAAsB,EAA2C,CAC9E,OAAO,EAAkC,CAAY,CACvD,CAEA,eAAe,EAAc,EAA+C,CAC1E,OAAO,EAAkB,CAAO,CAClC,CAEA,eAAe,EAAwB,EAAyD,CAC9F,IAAI,EAEJ,GAAI,CACF,EAAmB,MAAM,EAAkB,CAAO,CACpD,MAAiB,CACf,EAAmB,CACjB,YAAa,IAAA,GACb,OAAQ,CAAE,QAAS,GAAO,SAAU,EAAM,EAC1C,OAAQ,IAAA,GACR,KAAM,IAAA,GACN,SAAU,IAAA,EACZ,CACF,CAEA,IAAM,EAAY,MAAM,EAAsB,CAAO,EAC/C,EAAmC,CACvC,QAAS,EAAiB,QAAQ,SAAW,GAC7C,SAAU,EAAiB,QAAQ,UAAY,GAC/C,WACF,EACA,MAAO,CAAE,GAAG,EAAkB,QAAO,CACvC,CAEA,eAAe,EAA6B,EAAyB,EAAyB,CACvF,KAEL,GAAI,CACF,MAAM,EAAe,uCAAuC,EAAc,CAAI,CAChF,MAAiB,CAEjB,CACF,CAEA,eAAe,EAAgB,EAAyB,EAAiC,CAAC,EAAG,CAC3F,IAAM,EAAiB,EAAa,IAAI,EAExC,GAAI,EAAY,CAAY,EAAG,CAC7B,IAAM,EAAmB,MAAM,EAAe,oBAAoB,CAAY,EAC9E,MAAM,QAAQ,IAAI,EAAiB,IAAK,GAAQ,GAAA,EAAA,EAAA,IAAA,CAAoB,CAAG,EAAG,CAAO,CAAC,CAAC,CACrF,CAEA,IAAI,EACJ,GAAI,CACF,EAAU,MAAM,EAAM,QAAQ,OAAO,EAAa,MAAO,CAAE,OAAQ,QAAS,CAAC,EAC7E,EAAA,6BAA6B,EAAS,SAAU,CAAE,cAAe,EAAK,CAAC,CACzE,OAAS,EAAO,CACd,GAAI,CAAC,EAAA,eAAe,CAAK,EACvB,MAAM,CAEV,CAYA,OAVI,EAAQ,mBACV,MAAM,EAA6B,EAAc,EAAQ,IAAI,EAG3D,GACF,EAAM,cAAc,EAAgB,EAAA,GAAG,IAAI,UAAU,EAAG,EAAc,EAAe,IAAI,CAAC,EAG5F,EAAM,eAAe,CAAY,EACjC,EAAM,QAAQ,OAAO,EAAa,IAAI,CAAC,EAChC,CACT,CAEA,eAAe,EAAmC,EAAyB,EAAyB,CAClG,MAAM,EAAgB,EAAc,CAAE,kBAAmB,GAAM,MAAK,CAAC,CACvE,CAEA,eAAe,EAAwB,EAA8D,CACnG,GAAI,CAAC,GAAgB,CAAC,EAAM,SAAW,CAAC,EAAM,SAAW,OAAO,EAAM,QAAQ,SAAY,WAAY,MAAO,GAE7G,IAAM,EAAc,EAAa,KAAO,EAAa,OAAS,GAC9D,GAAI,CAAC,EAAa,MAAO,GAEzB,IAAM,EAAW,EAAM,QAAQ,SAAS,EAAa,CAAK,EAC1D,GAAI,IAAa,IAAS,IAAa,IAAA,GACrC,MAAO,GAGT,GAAI,CACF,MAAM,EAAM,QAAQ,QAAQ,CAAY,CAC1C,OAAS,EAAO,CACd,MAAM,aAAiB,MAAQ,EAAY,MAAM,sBAAsB,EAAY,EAAE,CACvF,CAEA,IAAM,EAAuB,EAAM,QAAQ,SAAS,EAAa,CAAK,EACtE,OAAO,IAAyB,IAAS,IAAyB,IAAA,EACpE,CAEA,MAAO,CACL,kBACA,qCACA,gBACA,0BACA,0BACA,kBACA,cACA,yBACF,CACF"}
|
|
@@ -114,11 +114,26 @@ function o(o, s, c, l) {
|
|
|
114
114
|
user: t
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
|
+
async function S(e) {
|
|
118
|
+
if (!e || !o.updater || !o.fetcher || typeof o.fetcher.refresh != "function") return !1;
|
|
119
|
+
let t = e.uri || e.value || "";
|
|
120
|
+
if (!t) return !1;
|
|
121
|
+
let n = o.updater.editable(t, o);
|
|
122
|
+
if (n !== !1 && n !== void 0) return !0;
|
|
123
|
+
try {
|
|
124
|
+
await o.fetcher.refresh(e);
|
|
125
|
+
} catch (e) {
|
|
126
|
+
throw e instanceof Error ? e : /* @__PURE__ */ Error(`Failed to refresh <${t}>`);
|
|
127
|
+
}
|
|
128
|
+
let r = o.updater.editable(t, o);
|
|
129
|
+
return r !== !1 && r !== void 0;
|
|
130
|
+
}
|
|
117
131
|
return {
|
|
118
132
|
recursiveDelete: b,
|
|
119
133
|
deleteResourceAndTypeIndexIfExists: x,
|
|
120
134
|
fetchMetadata: _,
|
|
121
135
|
fetchMetadataWithDelete: v,
|
|
136
|
+
checkAndRefreshEditable: S,
|
|
122
137
|
createContainer: u,
|
|
123
138
|
isContainer: d,
|
|
124
139
|
getContainerMemberCount: f
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resourceLogic.esm.js","names":[],"sources":["../../src/resource/resourceLogic.ts"],"sourcesContent":["import { NamedNode, sym } from 'rdflib'\nimport { ACL_LINK } from '../acl/aclLogic'\nimport { ns } from '../util/ns'\nimport { assertSuccessfulHttpResponse, isMissingError } from './resourceHttp'\nimport { readWacAccessInfo } from './resourceMetadata'\nimport { type AclLogic, type ResourceAccess, type ResourceAccessWithDelete, type ResourceDeleteOptions, type ResourceLogic, type ResourceMetadata, type ResourceMetadataWithDelete, type TypeIndexLogic } from '../types'\n\nexport function createResourceLogic(store, aclLogic: AclLogic, containerLogic, typeIndexLogic: TypeIndexLogic): ResourceLogic {\n function createContainer(url: string) {\n return containerLogic.createContainer(url)\n }\n\n function isContainer(resourceNode: NamedNode) {\n return containerLogic.isContainer(resourceNode)\n }\n\n function getContainerMemberCount(resourceNode: NamedNode) {\n return containerLogic.getContainerMemberCount(resourceNode)\n }\n\n function readMetadata(subject: NamedNode, response: Response): ResourceMetadata {\n let contentType: string | undefined\n let canEdit = false\n let isPublic = false\n let eTag: string | undefined\n let modified: string | undefined\n\n if (response.headers) {\n const contentTypeHeader = response.headers.get('content-type')\n contentType = contentTypeHeader?.split(';')[0] ?? undefined\n\n const accessFlags = readWacAccessInfo(response.headers.get('wac-allow'))\n canEdit = accessFlags.canEdit\n isPublic = accessFlags.isPublic\n eTag = response.headers.get('etag') ?? undefined\n modified = store.anyValue(subject as any, ns.dct('modified')) || store.anyValue(subject as any, ns.dc('modified')) || undefined\n }\n\n if ((!response.headers || !response.headers.get('content-type')) && (!response.headers || !response.headers.get('wac-allow') || !response.headers.get('etag'))) {\n const reqs = store.each(\n null,\n store.sym('http://www.w3.org/2007/ont/link#requestedURI'),\n subject\n )\n reqs.map((req: any) => {\n const responseNode = store.any(\n req as any,\n store.sym('http://www.w3.org/2007/ont/link#response')\n )\n if (responseNode && responseNode.termType === 'NamedNode') {\n const responseContentType = store.anyValue(responseNode as any, ns.httph('content-type')) || undefined\n if (contentType === undefined) {\n contentType = responseContentType\n }\n const wacAllow = (store.anyValue(responseNode as any, ns.httph('wac-allow')) as string | undefined) ||\n (store.anyValue(responseNode as any, ns.httph('WAC-Allow')) as string | undefined)\n const accessFlags = readWacAccessInfo(wacAllow)\n canEdit = canEdit || accessFlags.canEdit\n isPublic = isPublic || accessFlags.isPublic\n const responseETag = store.anyValue(responseNode as any, ns.httph('etag')) || undefined\n if (eTag === undefined) {\n eTag = responseETag\n }\n modified = store.anyValue(subject as any, ns.dct('modified')) || store.anyValue(subject as any, ns.dc('modified')) || undefined\n }\n })\n }\n\n const aclUri = store.any(subject, ACL_LINK)?.value || undefined\n const access: ResourceAccess = { canEdit, isPublic }\n return { contentType, access, aclUri, eTag, modified }\n }\n\n async function fetchHeadMetadata(subject: NamedNode): Promise<ResourceMetadata> {\n const response = await store.fetcher.webOperation('HEAD', subject.uri)\n assertSuccessfulHttpResponse(response, 'HEAD')\n return readMetadata(subject, response)\n }\n\n async function userCanWriteToContainingContainer(resourceNode: NamedNode): Promise<boolean> {\n const containerNode = store.any(resourceNode, ns.ldp('contains')) || resourceNode.dir()\n if (!containerNode || containerNode.termType !== 'NamedNode') {\n return false\n }\n\n try {\n const containerMetadata = await fetchHeadMetadata(containerNode as NamedNode)\n return containerMetadata.access.canEdit\n } catch (_error) {\n return false\n }\n }\n\n async function userCanDeleteResource(resourceNode: NamedNode): Promise<boolean> {\n return userCanWriteToContainingContainer(resourceNode)\n }\n\n async function fetchMetadata(subject: NamedNode): Promise<ResourceMetadata> {\n return fetchHeadMetadata(subject)\n }\n\n async function fetchMetadataWithDelete(subject: NamedNode): Promise<ResourceMetadataWithDelete> {\n let resourceMetadata: ResourceMetadata\n\n try {\n resourceMetadata = await fetchHeadMetadata(subject)\n } catch (_error) {\n resourceMetadata = {\n contentType: undefined,\n access: { canEdit: false, isPublic: false },\n aclUri: undefined,\n eTag: undefined,\n modified: undefined\n }\n }\n\n const canDelete = await userCanDeleteResource(subject)\n const access: ResourceAccessWithDelete = {\n canEdit: resourceMetadata.access?.canEdit ?? false,\n isPublic: resourceMetadata.access?.isPublic ?? false,\n canDelete\n }\n return { ...resourceMetadata, access }\n }\n\n async function deleteTypeIndexesForResource(resourceNode: NamedNode, user?: NamedNode | null) {\n if (!user) return\n\n try {\n await typeIndexLogic.deleteTypeIndexRegistrationForResource(resourceNode, user)\n } catch (_error) {\n // Keep resource deletion best-effort even if type-index cleanup fails.\n }\n }\n\n async function recursiveDelete(resourceNode: NamedNode, options: ResourceDeleteOptions = {}) {\n const resourceParent = resourceNode.dir()\n\n if (isContainer(resourceNode)) {\n const containerMembers = await containerLogic.getContainerMembers(resourceNode)\n await Promise.all(containerMembers.map((url) => recursiveDelete(sym(url), options)))\n }\n\n let deleted\n try {\n deleted = await store.fetcher._fetch(resourceNode.value, { method: 'DELETE' })\n assertSuccessfulHttpResponse(deleted, 'DELETE', { allowNotFound: true })\n } catch (error) {\n if (!isMissingError(error)) {\n throw error\n }\n }\n\n if (options.deleteTypeIndexes) {\n await deleteTypeIndexesForResource(resourceNode, options.user)\n }\n\n if (resourceParent) {\n store.removeMatches(resourceParent, ns.ldp('contains'), resourceNode, resourceParent.doc())\n }\n\n store.removeDocument(resourceNode)\n store.fetcher.unload(resourceNode.doc())\n return deleted\n }\n\n async function deleteResourceAndTypeIndexIfExists(resourceNode: NamedNode, user?: NamedNode | null) {\n await recursiveDelete(resourceNode, { deleteTypeIndexes: true, user })\n }\n\n return {\n recursiveDelete,\n deleteResourceAndTypeIndexIfExists,\n fetchMetadata,\n fetchMetadataWithDelete,\n createContainer,\n isContainer,\n getContainerMemberCount\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resourceLogic.esm.js","names":[],"sources":["../../src/resource/resourceLogic.ts"],"sourcesContent":["import { NamedNode, sym, LiveStore } from 'rdflib'\nimport { ACL_LINK } from '../acl/aclLogic'\nimport { ns } from '../util/ns'\nimport { assertSuccessfulHttpResponse, isMissingError } from './resourceHttp'\nimport { readWacAccessInfo } from './resourceMetadata'\nimport { type AclLogic, type ResourceAccess, type ResourceAccessWithDelete, type ResourceDeleteOptions, type ResourceLogic, type ResourceMetadata, type ResourceMetadataWithDelete, type TypeIndexLogic } from '../types'\n\nexport function createResourceLogic(store: LiveStore, aclLogic: AclLogic, containerLogic, typeIndexLogic: TypeIndexLogic): ResourceLogic {\n function createContainer(url: string) {\n return containerLogic.createContainer(url)\n }\n\n function isContainer(resourceNode: NamedNode) {\n return containerLogic.isContainer(resourceNode)\n }\n\n function getContainerMemberCount(resourceNode: NamedNode) {\n return containerLogic.getContainerMemberCount(resourceNode)\n }\n\n function readMetadata(subject: NamedNode, response: Response): ResourceMetadata {\n let contentType: string | undefined\n let canEdit = false\n let isPublic = false\n let eTag: string | undefined\n let modified: string | undefined\n\n if (response.headers) {\n const contentTypeHeader = response.headers.get('content-type')\n contentType = contentTypeHeader?.split(';')[0] ?? undefined\n\n const accessFlags = readWacAccessInfo(response.headers.get('wac-allow'))\n canEdit = accessFlags.canEdit\n isPublic = accessFlags.isPublic\n eTag = response.headers.get('etag') ?? undefined\n modified = store.anyValue(subject as any, ns.dct('modified')) || store.anyValue(subject as any, ns.dc('modified')) || undefined\n }\n\n if ((!response.headers || !response.headers.get('content-type')) && (!response.headers || !response.headers.get('wac-allow') || !response.headers.get('etag'))) {\n const reqs = store.each(\n null,\n store.sym('http://www.w3.org/2007/ont/link#requestedURI'),\n subject\n )\n reqs.map((req: any) => {\n const responseNode = store.any(\n req as any,\n store.sym('http://www.w3.org/2007/ont/link#response')\n )\n if (responseNode && responseNode.termType === 'NamedNode') {\n const responseContentType = store.anyValue(responseNode as any, ns.httph('content-type')) || undefined\n if (contentType === undefined) {\n contentType = responseContentType\n }\n const wacAllow = (store.anyValue(responseNode as any, ns.httph('wac-allow')) as string | undefined) ||\n (store.anyValue(responseNode as any, ns.httph('WAC-Allow')) as string | undefined)\n const accessFlags = readWacAccessInfo(wacAllow)\n canEdit = canEdit || accessFlags.canEdit\n isPublic = isPublic || accessFlags.isPublic\n const responseETag = store.anyValue(responseNode as any, ns.httph('etag')) || undefined\n if (eTag === undefined) {\n eTag = responseETag\n }\n modified = store.anyValue(subject as any, ns.dct('modified')) || store.anyValue(subject as any, ns.dc('modified')) || undefined\n }\n })\n }\n\n const aclUri = store.any(subject, ACL_LINK)?.value || undefined\n const access: ResourceAccess = { canEdit, isPublic }\n return { contentType, access, aclUri, eTag, modified }\n }\n\n async function fetchHeadMetadata(subject: NamedNode): Promise<ResourceMetadata> {\n const response = await store.fetcher.webOperation('HEAD', subject.uri)\n assertSuccessfulHttpResponse(response, 'HEAD')\n return readMetadata(subject, response)\n }\n\n async function userCanWriteToContainingContainer(resourceNode: NamedNode): Promise<boolean> {\n const containerNode = store.any(resourceNode, ns.ldp('contains')) || resourceNode.dir()\n if (!containerNode || containerNode.termType !== 'NamedNode') {\n return false\n }\n\n try {\n const containerMetadata = await fetchHeadMetadata(containerNode as NamedNode)\n return containerMetadata.access.canEdit\n } catch (_error) {\n return false\n }\n }\n\n async function userCanDeleteResource(resourceNode: NamedNode): Promise<boolean> {\n return userCanWriteToContainingContainer(resourceNode)\n }\n\n async function fetchMetadata(subject: NamedNode): Promise<ResourceMetadata> {\n return fetchHeadMetadata(subject)\n }\n\n async function fetchMetadataWithDelete(subject: NamedNode): Promise<ResourceMetadataWithDelete> {\n let resourceMetadata: ResourceMetadata\n\n try {\n resourceMetadata = await fetchHeadMetadata(subject)\n } catch (_error) {\n resourceMetadata = {\n contentType: undefined,\n access: { canEdit: false, isPublic: false },\n aclUri: undefined,\n eTag: undefined,\n modified: undefined\n }\n }\n\n const canDelete = await userCanDeleteResource(subject)\n const access: ResourceAccessWithDelete = {\n canEdit: resourceMetadata.access?.canEdit ?? false,\n isPublic: resourceMetadata.access?.isPublic ?? false,\n canDelete\n }\n return { ...resourceMetadata, access }\n }\n\n async function deleteTypeIndexesForResource(resourceNode: NamedNode, user?: NamedNode | null) {\n if (!user) return\n\n try {\n await typeIndexLogic.deleteTypeIndexRegistrationForResource(resourceNode, user)\n } catch (_error) {\n // Keep resource deletion best-effort even if type-index cleanup fails.\n }\n }\n\n async function recursiveDelete(resourceNode: NamedNode, options: ResourceDeleteOptions = {}) {\n const resourceParent = resourceNode.dir()\n\n if (isContainer(resourceNode)) {\n const containerMembers = await containerLogic.getContainerMembers(resourceNode)\n await Promise.all(containerMembers.map((url) => recursiveDelete(sym(url), options)))\n }\n\n let deleted\n try {\n deleted = await store.fetcher._fetch(resourceNode.value, { method: 'DELETE' })\n assertSuccessfulHttpResponse(deleted, 'DELETE', { allowNotFound: true })\n } catch (error) {\n if (!isMissingError(error)) {\n throw error\n }\n }\n\n if (options.deleteTypeIndexes) {\n await deleteTypeIndexesForResource(resourceNode, options.user)\n }\n\n if (resourceParent) {\n store.removeMatches(resourceParent, ns.ldp('contains'), resourceNode, resourceParent.doc())\n }\n\n store.removeDocument(resourceNode)\n store.fetcher.unload(resourceNode.doc())\n return deleted\n }\n\n async function deleteResourceAndTypeIndexIfExists(resourceNode: NamedNode, user?: NamedNode | null) {\n await recursiveDelete(resourceNode, { deleteTypeIndexes: true, user })\n }\n\n async function checkAndRefreshEditable(resourceNode: NamedNode | null | undefined): Promise<boolean> {\n if (!resourceNode || !store.updater || !store.fetcher || typeof store.fetcher.refresh !== 'function') return false\n\n const resourceUri = resourceNode.uri || resourceNode.value || ''\n if (!resourceUri) return false\n\n const editable = store.updater.editable(resourceUri, store)\n if (editable !== false && editable !== undefined) {\n return true\n }\n\n try {\n await store.fetcher.refresh(resourceNode)\n } catch (error) {\n throw error instanceof Error ? error : new Error(`Failed to refresh <${resourceUri}>`)\n }\n\n const editableAfterRefresh = store.updater.editable(resourceUri, store)\n return editableAfterRefresh !== false && editableAfterRefresh !== undefined\n }\n\n return {\n recursiveDelete,\n deleteResourceAndTypeIndexIfExists,\n fetchMetadata,\n fetchMetadataWithDelete,\n checkAndRefreshEditable,\n createContainer,\n isContainer,\n getContainerMemberCount\n }\n}\n"],"mappings":"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"}
|