@final-hill/decorator-contracts
Version:
Code Contracts for TypeScript and ECMAScript classes
2 lines • 5.49 kB
JavaScript
Symbol.metadata??=Symbol.for("Symbol.metadata");class t extends Error{}function e(e,r="Assertion Error"){if(0==Boolean(e))throw new t(r)}function r(t,e){return t&&e||!t&&!e}function n(t,e){return!t||e}function a(t,r){if(!h[u])return;h[u]=!1;const n=t[Symbol.metadata]?.invariants??[];try{for(const a of n)e(a(r),`Invariant violated in class ${t.name}: ${a.toString()}`)}finally{h[u]=!0}}const o=t=>(r,{kind:n,metadata:a})=>{e("class"===n,"@invariant decorator can only be applied to classes"),e(r.prototype instanceof h,"@invariant decorator can only be applied to classes that extend Contracted");const o=a.invariants??[];a.invariants=[...o,t]},s=t=>(r,n)=>{e(["method","getter","setter"].includes(n.kind),"@demands decorator can only be applied to methods, getters, or setters"),e(!1===n.static,"@demands decorator cannot be applied to static features"),e(!1===n.private,"@demands decorator cannot be applied to private/protected features"),e(!String(n.name).startsWith("_"),"@demands decorator cannot be applied to private/protected features"),n.addInitializer((function(){e(this instanceof h,"@demands decorator can only be applied to classes that extend Contracted");const r=[...n.metadata?.demands?.[n.name]??[],t];n.metadata.demands={...n.metadata?.demands??{},[n.name]:r}}))};function c(t,r,...n){if(!h[u])return;h[u]=!1;const a=t.constructor,o=a[Symbol.metadata]?.demands?.[r]??[];try{if(0===o.length)return;for(const e of o)if(e(t,...n))return;e(!1,`No demands were satisfied for ${t.constructor.name}.${String(r)}`)}finally{h[u]=!0}}const i=t=>(r,n)=>{e(["method","getter","setter"].includes(n.kind),"@ensures decorator can only be applied to methods, getters, or setters"),e(!1===n.static,"@ensures decorator cannot be applied to static features"),e(!1===n.private,"@ensures decorator cannot be applied to private features"),e(!String(n.name).startsWith("_"),"@ensures decorator cannot be applied to private/protected features"),n.addInitializer((function(){e(this instanceof h,"@ensures decorator can only be applied to classes that extend Contracted");const r=[...n.metadata?.ensures?.[n.name]??[],t];n.metadata.ensures={...n.metadata?.ensures??{},[n.name]:r}}))};function d(t,r,n,a){if(!h[u])return;h[u]=!1;const o=t.constructor,s=o[Symbol.metadata]?.ensures?.[n]??[];try{if(0===s.length)return;for(const o of s)o(t,a,r)||e(!1,`No ensurances were satisfied for ${t.constructor.name}.${String(n)}`)}finally{h[u]=!0}}const l=t=>(r,n)=>{e(["method","getter","setter"].includes(n.kind),"@rescue decorator can only be applied to methods, getters, or setters"),e(!1===n.static,"@rescue decorator cannot be applied to static features"),e(!1===n.private,"@rescue decorator cannot be applied to private features"),e(!String(n.name).startsWith("_"),"@rescue decorator cannot be applied to private/protected features"),n.addInitializer((function(){e(this instanceof h,"@rescue decorator can only be applied to classes that extend Contracted"),n.metadata.rescue={...n.metadata?.rescue??{},[n.name]:t}}))},f=(t,r,n,a,o)=>{if(!h[u])return a;const s=r.constructor,c=Object.getOwnPropertyDescriptor(s.prototype,n),i=s[Symbol.metadata]?.rescue?.[n];if(!i)throw a;let d,l=!1;h[u]=!1;try{if(i.call(r,r,a,o,((...a)=>{e(!l,"retry can only be called once"),l=!0,h[u]=!0,"get"==t?d=Reflect.get(r,n,r):"set"==t?d=Reflect.set(r,n,a[0],r):"func"==t&&(d=Reflect.apply(c.value,r,a))})),!l)throw a}finally{h[u]=!0}return d},u=Symbol.for("Contracted.checkedMode"),p=t=>{if(!h[u])return;h[u]=!1;const e=Object.create(t);for(const r in t)Reflect.set(e,r,Reflect.get(t,r));return h[u]=!0,e};function y(t,e){let r=t;for(;r&&r!==Object.prototype;){const t=Object.getOwnPropertyDescriptor(r,e);if(t)return t;r=Object.getPrototypeOf(r)}}const m={get(t,e,r){if(!h[u])return Reflect.get(t,e,r);const n=t.constructor,o=y(Object.getPrototypeOf(t),e),s=(n[Symbol.metadata]?.ensures?.[e]??[]).length>0,i=s?p(t):void 0;if("function"==typeof o?.value)return function(...r){let l;a(n,t),c(t,e,r);try{l=Reflect.apply(o.value,t,r),s&&d(t,i,e,r)}catch(n){l=f("func",t,e,n,r)}finally{a(n,t)}return l};if("function"==typeof o?.get){let o;a(n,t),c(t,e,[]);try{o=Reflect.get(t,e,r),s&&d(t,i,e,[o])}catch(r){o=f("get",t,e,r,[])}finally{a(n,t)}return o}return Reflect.get(t,e,r)},set(t,e,r,n){if(!h[u])return Reflect.set(t,e,r,n);const o=y(Object.getPrototypeOf(t),e);if(!(o&&"function"==typeof o.set||"string"!=typeof e||e.startsWith("_")))throw new TypeError(`Cannot assign to property '${String(e)}': only properties starting with '_' or with a setter can be set on Contracted instances.`);const s=t.constructor,i=(s[Symbol.metadata]?.ensures?.[e]??[]).length>0,l=i?p(t):void 0;let m;a(s,t),c(t,e,[r]);try{m=Reflect.set(t,e,r,n),i&&d(t,l,e,[r])}catch(n){m=f("set",t,e,n,[r])}finally{a(s,t)}return m},deleteProperty(t,e){throw new TypeError(`Cannot delete property '${String(e)}' from Contracted instances.`)}};class h{static[Symbol.metadata];static _allowConstruction=!1;static[u]=!0;static new(...t){this._allowConstruction=!0;try{const e=new this(...t);return a(this,e),new Proxy(e,m)}finally{this._allowConstruction=!1}}constructor(...t){if(!this.constructor._allowConstruction)throw new TypeError("Use the static 'new' method to instantiate this class.")}}export{t as AssertionError,h as Contracted,f as applyRescueHandler,e as assert,c as assertDemands,d as assertEnsures,a as assertInvariants,u as checkedMode,s as demands,i as ensures,r as iff,n as implies,o as invariant,l as rescue};
//# sourceMappingURL=index.mjs.map