@idos-network/instrumentation 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -71,12 +71,13 @@ Two things that look like they should work and do not:
71
71
 
72
72
  ## What gets traced
73
73
 
74
- | Module | Spans |
75
- | -------------------------- | -------------------------------------------------------------------------------------------------- |
76
- | `@idos-network/kwil-infra` | `KwilActionClient.call` / `.execute` — the idOS equivalent of `pg.Client.query` — and `.waitForTx` |
77
- | `@idos-network/client` | `idOSClientConfiguration` / `Idle` / `WithUserSigner` / `LoggedIn` methods |
78
- | `@idos-network/issuer` | `idOSIssuer` methods and `idOSIssuer.init` |
79
- | `@idos-network/consumer` | `idOSConsumer` methods and `idOSConsumer.init` |
74
+ | Module | Spans |
75
+ | --------------------------- | -------------------------------------------------------------------------------------------------- |
76
+ | `@idos-network/kwil-infra` | `KwilActionClient.call` / `.execute` — the idOS equivalent of `pg.Client.query` — and `.waitForTx` |
77
+ | `@idos-network/client` | `idOSClientConfiguration` / `Idle` / `WithUserSigner` / `LoggedIn` methods |
78
+ | `@idos-network/issuer` | `idOSIssuer` methods and `idOSIssuer.init` |
79
+ | `@idos-network/mm-operator` | `idOSMmOperator` methods and `idOSMmOperator.init` |
80
+ | `@idos-network/consumer` | `idOSConsumer` methods and `idOSConsumer.init` |
80
81
 
81
82
  The enclave is not traced: it is local key material and iframe/MPC work, not
82
83
  where request latency lives. `verifyCredential` is covered as
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/instrumentation.ts","../src/semconv.ts","../src/targets.ts"],"mappings":";;;;KAIY;;EAEV;;EAEA;;EAEA;;EAEA;;;KAIU;EACV;EACA;EACA;;EAEA;;KAGU,kCAAkC,MAAM,MAAM,MAAM;KAEpD,mCACV,MAAM,MACN,MAAM;UAGS,kCAAkC;;;;;;;;;EASjD,cAAc;;;;;;;;EASd,eAAe;;;;;;;;;EAUf;;;;;;;;;qBChCW,4BAA4B,oBAAoB;EAC3D,YAAY,SAAQ;YAIV,QAAQ;;;;;;;;;;;EAsBlB,mBAAmB,oBAAoB;;EAMvC,qBAAqB,oBAAoB;UAKjC;UAMA;UAUA;;UAQA;UAmDA;UA+DA;UAmBA;;;;;;;;;;qBCvNG;;qBAGA;;qBAGA;;qBAGA;;qBAGA;;qBAGA;;qBAGA;;;;KCRD;EACV;;EAEA,YAAY;;EAEZ,cAAc,6BAA6B;;EAE3C,sBAAsB,oBAAoB;;EAE1C,OAAO;;KAGG;;EAEV;;EAEA,mBAAmB;;EAEnB,0BAA0B;;KAGhB;;EAEV;EACA;;;;;;;;EAQA,SAAS;;qBAyDE,SAAS"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/instrumentation.ts","../src/semconv.ts","../src/targets.ts"],"mappings":";;;;KAIY;;EAEV;;EAEA;;EAEA;;EAEA;;;KAIU;EACV;EACA;EACA;;EAEA;;KAGU,kCAAkC,MAAM,MAAM,MAAM;KAEpD,mCACV,MAAM,MACN,MAAM;UAGS,kCAAkC;;;;;;;;;EASjD,cAAc;;;;;;;;EASd,eAAe;;;;;;;;;EAUf;;;;;;;;;qBChCW,4BAA4B,oBAAoB;EAC3D,YAAY,SAAQ;YAIV,QAAQ;;;;;;;;;;;EAsBlB,mBAAmB,oBAAoB;;EAMvC,qBAAqB,oBAAoB;UAKjC;UAMA;UAUA;;UAQA;UAmDA;UA+DA;UAmBA;;;;;;;;;;qBCvNG;;qBAGA;;qBAGA;;qBAGA;;qBAGA;;qBAGA;;qBAGA;;;;KCRD;EACV;;EAEA,YAAY;;EAEZ,cAAc,6BAA6B;;EAE3C,sBAAsB,oBAAoB;;EAE1C,OAAO;;KAGG;;EAEV;;EAEA,mBAAmB;;EAEnB,0BAA0B;;KAGhB;;EAEV;EACA;;;;;;;;EAQA,SAAS;;qBA0DE,SAAS"}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{SpanKind as e,SpanStatusCode as t,trace as n}from"@opentelemetry/api";import{InstrumentationBase as r,InstrumentationNodeModuleDefinition as i,isWrapped as a}from"@opentelemetry/instrumentation";import{ATTR_DB_NAMESPACE as o,ATTR_DB_OPERATION_NAME as s,ATTR_DB_SYSTEM_NAME as c,ATTR_ERROR_TYPE as l}from"@opentelemetry/semantic-conventions";const u=`idos.sdk.package`,d=`idos.sdk.class`,f=`idos.sdk.method`,p=`kwil`,m=`main`,h=`idos.kwil.tx_hash`,g=`idos.kwil.synchronous`,_=[`>=2.0.0 <3`],v=e=>{let t=e[0];return{[c]:p,[o]:m,...typeof t?.name==`string`?{[s]:t.name}:{}}},y=e=>t=>{let n=t[0];return typeof n?.name==`string`?`idos.kwil.${e} ${n.name}`:`idos.kwil.${e}`},b=[{name:`@idos-network/kwil-infra`,supportedVersions:_,classes:[{className:`KwilActionClient`,methods:[{name:`call`,kind:e.CLIENT,spanName:y(`call`),attributes:v},{name:`execute`,kind:e.CLIENT,spanName:y(`execute`),attributes:e=>({...v(e),[g]:e[2]===void 0||!!e[2]}),responseAttributes:e=>typeof e==`string`?{[h]:e}:{}},{name:`waitForTx`,kind:e.CLIENT,spanName:()=>`idos.kwil.waitForTx`,attributes:e=>({[c]:p,[o]:m,...typeof e[0]==`string`?{[h]:e[0]}:{}})}]}]},{name:`@idos-network/client`,supportedVersions:_,classes:[{className:`idOSClientConfiguration`,methods:[`createClient`]},{className:`idOSClientIdle`,methods:[`addressHasProfile`,`withUserSigner`,`logOut`],staticMethods:[`fromConfig`]},{className:`idOSClientWithUserSigner`,methods:[`hasProfile`,`createUserEncryptionProfile`,`logIn`,`logOut`]},{className:`idOSClientLoggedIn`,methods:[`requestDWGMessage`,`createCredential`,`removeCredential`,`getCredentialById`,`shareCredential`,`getAllCredentials`,`getAccessGrantsOwned`,`getAttributes`,`createAttribute`,`getCredentialContentSha256Hash`,`getCredentialContent`,`getCredentialWithEncryptedContent`,`getCredentialSharedContent`,`getGrants`,`getGrantsCount`,`getCredentialShared`,`revokeAccessGrant`,`addWallet`,`addWallets`,`getWallets`,`removeWallet`,`removeWallets`,`filterCredentials`,`requestAccessGrant`,`logOut`]}]},{name:`@idos-network/issuer`,supportedVersions:_,classes:[{className:`idOSIssuer`,staticMethods:[`init`],methods:[`hasProfile`,`createUserProfile`,`upsertWalletAsInserter`,`createUser`,`getUser`,`requestDelegatedWriteGrantMessage`,`createCredentialByDelegatedWriteGrant`,`editCredentialAsIssuer`,`getCredentialIdByContentHash`,`getCredentialShared`]}]},{name:`@idos-network/consumer`,supportedVersions:_,classes:[{className:`idOSConsumer`,staticMethods:[`init`],methods:[`getCredentialSharedFromIDOS`,`getCredentialSharedContentDecrypted`,`rescindSharedCredential`,`getGrantsCount`,`getAccessGrantsForCredential`,`getCredentialsSharedByUser`,`getAccessGrants`,`verifyCredential`]}]}],x=e=>typeof e?.then==`function`;var S=class extends r{constructor(e={}){super(`@idos-network/instrumentation`,`2.0.1`,e)}init(){return b.map(e=>new i(e.name,e.supportedVersions,t=>this.applyPatch(e.name,e,t),t=>this.removePatch(e.name,e,t)))}patchModuleExports(e,t){let n=this.findTarget(e);n&&this.applyPatch(e,n,t)}unpatchModuleExports(e,t){let n=this.findTarget(e);n&&this.removePatch(e,n,t)}findTarget(e){let t=b.find(t=>t.name===e);return t||this._diag.warn(`No instrumentation targets known for "${e}"`),t}applyPatch(e,t,n){return this.eachMember(e,t,n,(t,n,r,i)=>{a(t[n])&&this._unwrap(t,n),this._wrap(t,n,t=>this.traced(t,e,i,r))}),n}removePatch(e,t,n){return this.eachMember(e,t,n,(e,t)=>{a(e[t])&&this._unwrap(e,t)}),n}eachMember(e,t,n,r){if(typeof n!=`object`||!n)return;let i=n,a=(t,n,i)=>{let a=typeof n==`string`?{name:n}:n,o=`${i?`${i}.`:``}${a.name}`;if(typeof t[a.name]!=`function`){this._diag.debug(`${e}: ${o} is not a function, skipping`);return}try{r(t,a.name,a,i)}catch(t){this._diag.warn(`${e}: could not patch ${o}: ${String(t)}`)}};for(let n of t.classes){let t=i[n.className];if(typeof t!=`function`){this._diag.debug(`${e}: class ${n.className} not exported, skipping`);continue}let r=t.prototype;if(typeof r==`object`&&r)for(let e of n.methods)a(r,e,n.className);for(let e of n.staticMethods??[])a(t,e,n.className)}}traced(t,r,i,a){let o=this,s=`${i?`${i}.`:``}${a.name}`;return function(...c){let l=o.getConfig();if(l.requireParentSpan&&n.getActiveSpan()===void 0)return t.apply(this,c);let p={[u]:r,[f]:a.name,...i?{[d]:i}:{},...a.attributes?.(c)},m=a.spanName?.(c)??s,h={kind:a.kind??e.INTERNAL,attributes:p};return o.tracer.startActiveSpan(m,h,e=>{o._runSpanCustomizationHook(l.requestHook,`requestHook`,e,{moduleName:r,className:i,methodName:a.name,args:c});let n;try{n=t.apply(this,c)}catch(t){throw o.failSpan(e,t),t}return x(n)?n.then(t=>(o.endSpan(e,r,i,a,t),t),t=>{throw o.failSpan(e,t),t}):(o.endSpan(e,r,i,a,n),n)})}}endSpan(e,t,n,r,i){let a=r.responseAttributes?.(i);a&&e.setAttributes(a),this._runSpanCustomizationHook(this.getConfig().responseHook,`responseHook`,e,{moduleName:t,className:n,methodName:r.name,result:i}),e.end()}failSpan(e,n){n instanceof Error?(e.recordException(n),e.setAttribute(l,n.name),e.setStatus({code:t.ERROR,message:n.message})):(e.setAttribute(l,typeof n),e.setStatus({code:t.ERROR,message:String(n)})),e.end()}};export{g as ATTR_IDOS_KWIL_SYNCHRONOUS,h as ATTR_IDOS_KWIL_TX_HASH,d as ATTR_IDOS_SDK_CLASS,f as ATTR_IDOS_SDK_METHOD,u as ATTR_IDOS_SDK_PACKAGE,m as IDOS_KWIL_NAMESPACE,p as IDOS_KWIL_SYSTEM,S as IdosInstrumentation,b as TARGETS};
1
+ import{SpanKind as e,SpanStatusCode as t,trace as n}from"@opentelemetry/api";import{InstrumentationBase as r,InstrumentationNodeModuleDefinition as i,isWrapped as a}from"@opentelemetry/instrumentation";import{ATTR_DB_NAMESPACE as o,ATTR_DB_OPERATION_NAME as s,ATTR_DB_SYSTEM_NAME as c,ATTR_ERROR_TYPE as l}from"@opentelemetry/semantic-conventions";const u=`idos.sdk.package`,d=`idos.sdk.class`,f=`idos.sdk.method`,p=`kwil`,m=`main`,h=`idos.kwil.tx_hash`,g=`idos.kwil.synchronous`,_=[`>=2.0.0 <3`],v=[`>=0.1.0 <1`],y=e=>{let t=e[0];return{[c]:p,[o]:m,...typeof t?.name==`string`?{[s]:t.name}:{}}},b=e=>t=>{let n=t[0];return typeof n?.name==`string`?`idos.kwil.${e} ${n.name}`:`idos.kwil.${e}`},x=[{name:`@idos-network/kwil-infra`,supportedVersions:_,classes:[{className:`KwilActionClient`,methods:[{name:`call`,kind:e.CLIENT,spanName:b(`call`),attributes:y},{name:`execute`,kind:e.CLIENT,spanName:b(`execute`),attributes:e=>({...y(e),[g]:e[2]===void 0||!!e[2]}),responseAttributes:e=>typeof e==`string`?{[h]:e}:{}},{name:`waitForTx`,kind:e.CLIENT,spanName:()=>`idos.kwil.waitForTx`,attributes:e=>({[c]:p,[o]:m,...typeof e[0]==`string`?{[h]:e[0]}:{}})}]}]},{name:`@idos-network/client`,supportedVersions:_,classes:[{className:`idOSClientConfiguration`,methods:[`createClient`]},{className:`idOSClientIdle`,methods:[`addressHasProfile`,`withUserSigner`,`logOut`],staticMethods:[`fromConfig`]},{className:`idOSClientWithUserSigner`,methods:[`hasProfile`,`createUserEncryptionProfile`,`logIn`,`logOut`]},{className:`idOSClientLoggedIn`,methods:[`requestDWGMessage`,`createCredential`,`removeCredential`,`getCredentialById`,`shareCredential`,`getAllCredentials`,`getAccessGrantsOwned`,`getAttributes`,`createAttribute`,`getCredentialContentSha256Hash`,`getCredentialContent`,`getCredentialWithEncryptedContent`,`getCredentialSharedContent`,`getGrants`,`getGrantsCount`,`getCredentialShared`,`revokeAccessGrant`,`addWallet`,`addWallets`,`getWallets`,`removeWallet`,`removeWallets`,`filterCredentials`,`requestAccessGrant`,`logOut`]}]},{name:`@idos-network/issuer`,supportedVersions:_,classes:[{className:`idOSIssuer`,staticMethods:[`init`],methods:[`hasProfile`,`createUserProfile`,`upsertWalletAsInserter`,`createUser`,`getUser`,`requestDelegatedWriteGrantMessage`,`createCredentialByDelegatedWriteGrant`,`editCredentialAsIssuer`,`getCredentialIdByContentHash`,`getCredentialShared`]}]},{name:`@idos-network/mm-operator`,supportedVersions:v,classes:[{className:`idOSMmOperator`,staticMethods:[`init`],methods:[`getUser`,`createUser`,`getCredentials`,`createCredential`,`getCredentialContent`,`requestUserWipe`,`wipeUser`]}]},{name:`@idos-network/consumer`,supportedVersions:_,classes:[{className:`idOSConsumer`,staticMethods:[`init`],methods:[`getCredentialSharedFromIDOS`,`getCredentialSharedContentDecrypted`,`rescindSharedCredential`,`getGrantsCount`,`getAccessGrantsForCredential`,`getCredentialsSharedByUser`,`getAccessGrants`,`verifyCredential`]}]}],S=e=>typeof e?.then==`function`;var C=class extends r{constructor(e={}){super(`@idos-network/instrumentation`,`2.0.1`,e)}init(){return x.map(e=>new i(e.name,e.supportedVersions,t=>this.applyPatch(e.name,e,t),t=>this.removePatch(e.name,e,t)))}patchModuleExports(e,t){let n=this.findTarget(e);n&&this.applyPatch(e,n,t)}unpatchModuleExports(e,t){let n=this.findTarget(e);n&&this.removePatch(e,n,t)}findTarget(e){let t=x.find(t=>t.name===e);return t||this._diag.warn(`No instrumentation targets known for "${e}"`),t}applyPatch(e,t,n){return this.eachMember(e,t,n,(t,n,r,i)=>{a(t[n])&&this._unwrap(t,n),this._wrap(t,n,t=>this.traced(t,e,i,r))}),n}removePatch(e,t,n){return this.eachMember(e,t,n,(e,t)=>{a(e[t])&&this._unwrap(e,t)}),n}eachMember(e,t,n,r){if(typeof n!=`object`||!n)return;let i=n,a=(t,n,i)=>{let a=typeof n==`string`?{name:n}:n,o=`${i?`${i}.`:``}${a.name}`;if(typeof t[a.name]!=`function`){this._diag.debug(`${e}: ${o} is not a function, skipping`);return}try{r(t,a.name,a,i)}catch(t){this._diag.warn(`${e}: could not patch ${o}: ${String(t)}`)}};for(let n of t.classes){let t=i[n.className];if(typeof t!=`function`){this._diag.debug(`${e}: class ${n.className} not exported, skipping`);continue}let r=t.prototype;if(typeof r==`object`&&r)for(let e of n.methods)a(r,e,n.className);for(let e of n.staticMethods??[])a(t,e,n.className)}}traced(t,r,i,a){let o=this,s=`${i?`${i}.`:``}${a.name}`;return function(...c){let l=o.getConfig();if(l.requireParentSpan&&n.getActiveSpan()===void 0)return t.apply(this,c);let p={[u]:r,[f]:a.name,...i?{[d]:i}:{},...a.attributes?.(c)},m=a.spanName?.(c)??s,h={kind:a.kind??e.INTERNAL,attributes:p};return o.tracer.startActiveSpan(m,h,e=>{o._runSpanCustomizationHook(l.requestHook,`requestHook`,e,{moduleName:r,className:i,methodName:a.name,args:c});let n;try{n=t.apply(this,c)}catch(t){throw o.failSpan(e,t),t}return S(n)?n.then(t=>(o.endSpan(e,r,i,a,t),t),t=>{throw o.failSpan(e,t),t}):(o.endSpan(e,r,i,a,n),n)})}}endSpan(e,t,n,r,i){let a=r.responseAttributes?.(i);a&&e.setAttributes(a),this._runSpanCustomizationHook(this.getConfig().responseHook,`responseHook`,e,{moduleName:t,className:n,methodName:r.name,result:i}),e.end()}failSpan(e,n){n instanceof Error?(e.recordException(n),e.setAttribute(l,n.name),e.setStatus({code:t.ERROR,message:n.message})):(e.setAttribute(l,typeof n),e.setStatus({code:t.ERROR,message:String(n)})),e.end()}};export{g as ATTR_IDOS_KWIL_SYNCHRONOUS,h as ATTR_IDOS_KWIL_TX_HASH,d as ATTR_IDOS_SDK_CLASS,f as ATTR_IDOS_SDK_METHOD,u as ATTR_IDOS_SDK_PACKAGE,m as IDOS_KWIL_NAMESPACE,p as IDOS_KWIL_SYSTEM,C as IdosInstrumentation,x as TARGETS};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/semconv.ts","../src/targets.ts","../src/version.ts","../src/instrumentation.ts"],"sourcesContent":["/**\n * Attributes emitted by this instrumentation that have no stable OpenTelemetry\n * semantic convention. Stable ones (`db.*`, `error.type`) are imported from\n * `@opentelemetry/semantic-conventions` at the call site.\n */\n\n/** Package the traced method lives in, e.g. `@idos-network/issuer`. */\nexport const ATTR_IDOS_SDK_PACKAGE = \"idos.sdk.package\";\n\n/** Class the traced method lives on, e.g. `idOSIssuer`. */\nexport const ATTR_IDOS_SDK_CLASS = \"idos.sdk.class\";\n\n/** Traced method name, e.g. `createUserProfile`. */\nexport const ATTR_IDOS_SDK_METHOD = \"idos.sdk.method\";\n\n/** `db.system.name` value for the idOS kwil network. */\nexport const IDOS_KWIL_SYSTEM = \"kwil\";\n\n/** Kwil namespace every idOS action runs against. */\nexport const IDOS_KWIL_NAMESPACE = \"main\";\n\n/** Transaction hash returned by a kwil `execute`. */\nexport const ATTR_IDOS_KWIL_TX_HASH = \"idos.kwil.tx_hash\";\n\n/** Whether a kwil `execute` waited for the transaction to be mined. */\nexport const ATTR_IDOS_KWIL_SYNCHRONOUS = \"idos.kwil.synchronous\";\n","import type { Attributes } from \"@opentelemetry/api\";\n\nimport { SpanKind } from \"@opentelemetry/api\";\nimport {\n ATTR_DB_NAMESPACE,\n ATTR_DB_OPERATION_NAME,\n ATTR_DB_SYSTEM_NAME,\n} from \"@opentelemetry/semantic-conventions\";\n\nimport {\n ATTR_IDOS_KWIL_SYNCHRONOUS,\n ATTR_IDOS_KWIL_TX_HASH,\n IDOS_KWIL_NAMESPACE,\n IDOS_KWIL_SYSTEM,\n} from \"./semconv\";\n\n/** A method to wrap. A bare string uses every default. */\nexport type MethodTarget = {\n name: string;\n /** Span name. Defaults to `<Class>.<method>`, or `<method>` for a function export. */\n spanName?: (args: readonly unknown[]) => string;\n /** Attributes derived from the arguments. Must not emit personal data. */\n attributes?: (args: readonly unknown[]) => Attributes;\n /** Attributes derived from the resolved value. Must not emit personal data. */\n responseAttributes?: (result: unknown) => Attributes;\n /** @default SpanKind.INTERNAL */\n kind?: SpanKind;\n};\n\nexport type ClassTarget = {\n /** Name of the class as exported by the module. */\n className: string;\n /** Instance methods, wrapped on the prototype. */\n methods: (string | MethodTarget)[];\n /** Static methods, wrapped on the constructor (`init`-style factories). */\n staticMethods?: (string | MethodTarget)[];\n};\n\nexport type ModuleTarget = {\n /** Module specifier. */\n name: string;\n supportedVersions: string[];\n /**\n * Only classes. Every method lives on a prototype or a constructor, both of\n * which are ordinary mutable objects — that is what lets\n * {@link IdosInstrumentation.patchModuleExports} work without a loader hook.\n * A bare function export would sit on the sealed module namespace instead,\n * and could only be reached via `import-in-the-middle`.\n */\n classes: ClassTarget[];\n};\n\nconst SUPPORTED = [\">=2.0.0 <3\"];\n\n/**\n * Kwil `call`/`execute` are the idOS equivalent of `pg.Client.query`: every SDK\n * operation bottoms out here. The action name is a fixed identifier from the\n * action schema, so it is safe to record; the inputs are not.\n */\nconst kwilAttributes = (args: readonly unknown[]): Attributes => {\n const params = args[0] as { name?: unknown } | undefined;\n return {\n [ATTR_DB_SYSTEM_NAME]: IDOS_KWIL_SYSTEM,\n [ATTR_DB_NAMESPACE]: IDOS_KWIL_NAMESPACE,\n ...(typeof params?.name === \"string\" ? { [ATTR_DB_OPERATION_NAME]: params.name } : {}),\n };\n};\n\nconst kwilSpanName =\n (operation: string) =>\n (args: readonly unknown[]): string => {\n const params = args[0] as { name?: unknown } | undefined;\n return typeof params?.name === \"string\"\n ? `idos.kwil.${operation} ${params.name}`\n : `idos.kwil.${operation}`;\n };\n\n/** Methods shared by every logged-out-capable client state. */\nconst CLIENT_LOGGED_IN_METHODS = [\n \"requestDWGMessage\",\n \"createCredential\",\n \"removeCredential\",\n \"getCredentialById\",\n \"shareCredential\",\n \"getAllCredentials\",\n \"getAccessGrantsOwned\",\n \"getAttributes\",\n \"createAttribute\",\n \"getCredentialContentSha256Hash\",\n \"getCredentialContent\",\n \"getCredentialWithEncryptedContent\",\n \"getCredentialSharedContent\",\n \"getGrants\",\n \"getGrantsCount\",\n \"getCredentialShared\",\n \"revokeAccessGrant\",\n \"addWallet\",\n \"addWallets\",\n \"getWallets\",\n \"removeWallet\",\n \"removeWallets\",\n \"filterCredentials\",\n \"requestAccessGrant\",\n \"logOut\",\n];\n\nexport const TARGETS: ModuleTarget[] = [\n {\n name: \"@idos-network/kwil-infra\",\n supportedVersions: SUPPORTED,\n classes: [\n {\n className: \"KwilActionClient\",\n methods: [\n {\n name: \"call\",\n kind: SpanKind.CLIENT,\n spanName: kwilSpanName(\"call\"),\n attributes: kwilAttributes,\n },\n {\n name: \"execute\",\n kind: SpanKind.CLIENT,\n spanName: kwilSpanName(\"execute\"),\n attributes: (args) => ({\n ...kwilAttributes(args),\n // `synchronous` defaults to true and also decides whether the span\n // covers the tx-confirmation polling loop.\n [ATTR_IDOS_KWIL_SYNCHRONOUS]: args[2] === undefined ? true : Boolean(args[2]),\n }),\n responseAttributes: (result) =>\n typeof result === \"string\" ? { [ATTR_IDOS_KWIL_TX_HASH]: result } : {},\n },\n {\n // Usually the bulk of an `execute`: polling the node until the tx is\n // mined. A tx hash is a public chain identifier, so it is safe to record.\n name: \"waitForTx\",\n kind: SpanKind.CLIENT,\n spanName: () => \"idos.kwil.waitForTx\",\n attributes: (args) => ({\n [ATTR_DB_SYSTEM_NAME]: IDOS_KWIL_SYSTEM,\n [ATTR_DB_NAMESPACE]: IDOS_KWIL_NAMESPACE,\n ...(typeof args[0] === \"string\" ? { [ATTR_IDOS_KWIL_TX_HASH]: args[0] } : {}),\n }),\n },\n ],\n },\n ],\n },\n {\n name: \"@idos-network/client\",\n supportedVersions: SUPPORTED,\n classes: [\n { className: \"idOSClientConfiguration\", methods: [\"createClient\"] },\n {\n className: \"idOSClientIdle\",\n methods: [\"addressHasProfile\", \"withUserSigner\", \"logOut\"],\n staticMethods: [\"fromConfig\"],\n },\n {\n className: \"idOSClientWithUserSigner\",\n methods: [\"hasProfile\", \"createUserEncryptionProfile\", \"logIn\", \"logOut\"],\n },\n { className: \"idOSClientLoggedIn\", methods: CLIENT_LOGGED_IN_METHODS },\n ],\n },\n {\n name: \"@idos-network/issuer\",\n supportedVersions: SUPPORTED,\n classes: [\n {\n className: \"idOSIssuer\",\n staticMethods: [\"init\"],\n methods: [\n \"hasProfile\",\n \"createUserProfile\",\n \"upsertWalletAsInserter\",\n \"createUser\",\n \"getUser\",\n \"requestDelegatedWriteGrantMessage\",\n \"createCredentialByDelegatedWriteGrant\",\n \"editCredentialAsIssuer\",\n \"getCredentialIdByContentHash\",\n \"getCredentialShared\",\n ],\n },\n ],\n },\n {\n name: \"@idos-network/consumer\",\n supportedVersions: SUPPORTED,\n classes: [\n {\n className: \"idOSConsumer\",\n staticMethods: [\"init\"],\n methods: [\n \"getCredentialSharedFromIDOS\",\n \"getCredentialSharedContentDecrypted\",\n \"rescindSharedCredential\",\n \"getGrantsCount\",\n \"getAccessGrantsForCredential\",\n \"getCredentialsSharedByUser\",\n \"getAccessGrants\",\n \"verifyCredential\",\n ],\n },\n ],\n },\n];\n","// Keep in sync with package.json — it is the `otel.scope.version` of every emitted span.\nexport const PACKAGE_NAME = \"@idos-network/instrumentation\";\nexport const PACKAGE_VERSION = \"2.0.1\";\n","import type { Attributes, Span } from \"@opentelemetry/api\";\n\nimport { SpanKind, SpanStatusCode, trace } from \"@opentelemetry/api\";\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n isWrapped,\n} from \"@opentelemetry/instrumentation\";\nimport { ATTR_ERROR_TYPE } from \"@opentelemetry/semantic-conventions\";\n\nimport type { MethodTarget, ModuleTarget } from \"./targets\";\nimport type { IdosInstrumentationConfig } from \"./types\";\n\nimport { ATTR_IDOS_SDK_CLASS, ATTR_IDOS_SDK_METHOD, ATTR_IDOS_SDK_PACKAGE } from \"./semconv\";\nimport { TARGETS } from \"./targets\";\nimport { PACKAGE_NAME, PACKAGE_VERSION } from \"./version\";\n\ntype AnyMethod = (...args: unknown[]) => unknown;\n\nconst isThenable = (value: unknown): value is PromiseLike<unknown> =>\n typeof (value as PromiseLike<unknown> | null)?.then === \"function\";\n\n/**\n * Traces the idOS SDK: every public method of `@idos-network/client`,\n * `/consumer`, `/issuer`, the enclave providers, `verifyCredential`, and the\n * kwil `call`/`execute` round-trips they all bottom out in.\n */\nexport class IdosInstrumentation extends InstrumentationBase<IdosInstrumentationConfig> {\n constructor(config: IdosInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n }\n\n protected init(): InstrumentationNodeModuleDefinition[] {\n return TARGETS.map(\n (target) =>\n new InstrumentationNodeModuleDefinition(\n target.name,\n target.supportedVersions,\n (moduleExports: unknown) => this.applyPatch(target.name, target, moduleExports),\n (moduleExports: unknown) => this.removePatch(target.name, target, moduleExports),\n ),\n );\n }\n\n /**\n * Patch a module namespace you already imported.\n *\n * The automatic hooking in {@link InstrumentationBase} needs Node's module\n * loader hook (`import-in-the-middle`), which has to be installed with\n * `module.register()` before the import — and does not exist at all in a\n * browser or a bundled app. This is the alternative everywhere: import the\n * idOS module and hand its namespace over. Exports the module does not have\n * are skipped.\n */\n patchModuleExports(moduleName: string, moduleExports: unknown): void {\n const target = this.findTarget(moduleName);\n if (target) this.applyPatch(moduleName, target, moduleExports);\n }\n\n /** Reverse of {@link patchModuleExports}. */\n unpatchModuleExports(moduleName: string, moduleExports: unknown): void {\n const target = this.findTarget(moduleName);\n if (target) this.removePatch(moduleName, target, moduleExports);\n }\n\n private findTarget(moduleName: string): ModuleTarget | undefined {\n const target = TARGETS.find((t) => t.name === moduleName);\n if (!target) this._diag.warn(`No instrumentation targets known for \"${moduleName}\"`);\n return target;\n }\n\n private applyPatch(moduleName: string, target: ModuleTarget, moduleExports: unknown): unknown {\n this.eachMember(moduleName, target, moduleExports, (owner, name, method, className) => {\n if (isWrapped(owner[name])) this._unwrap(owner, name);\n this._wrap(owner, name, (original) =>\n this.traced(original as AnyMethod, moduleName, className, method),\n );\n });\n return moduleExports;\n }\n\n private removePatch(moduleName: string, target: ModuleTarget, moduleExports: unknown): unknown {\n this.eachMember(moduleName, target, moduleExports, (owner, name) => {\n if (isWrapped(owner[name])) this._unwrap(owner, name);\n });\n return moduleExports;\n }\n\n /** Resolves every target method to the object that owns it, skipping what is absent. */\n private eachMember(\n moduleName: string,\n target: ModuleTarget,\n moduleExports: unknown,\n visit: (\n owner: Record<string, unknown>,\n name: string,\n method: MethodTarget,\n className: string | undefined,\n ) => void,\n ): void {\n if (typeof moduleExports !== \"object\" || moduleExports === null) return;\n const namespace = moduleExports as Record<string, unknown>;\n\n const visitOne = (\n owner: Record<string, unknown>,\n member: string | MethodTarget,\n className: string | undefined,\n ): void => {\n const method: MethodTarget = typeof member === \"string\" ? { name: member } : member;\n const label = `${className ? `${className}.` : \"\"}${method.name}`;\n if (typeof owner[method.name] !== \"function\") {\n this._diag.debug(`${moduleName}: ${label} is not a function, skipping`);\n return;\n }\n try {\n visit(owner, method.name, method, className);\n } catch (error) {\n // An ESM namespace object is read-only unless an import hook made it writable.\n this._diag.warn(`${moduleName}: could not patch ${label}: ${String(error)}`);\n }\n };\n\n for (const klass of target.classes) {\n const ctor = namespace[klass.className];\n if (typeof ctor !== \"function\") {\n this._diag.debug(`${moduleName}: class ${klass.className} not exported, skipping`);\n continue;\n }\n const prototype = (ctor as { prototype?: unknown }).prototype;\n if (typeof prototype === \"object\" && prototype !== null) {\n for (const member of klass.methods) {\n visitOne(prototype as Record<string, unknown>, member, klass.className);\n }\n }\n for (const member of klass.staticMethods ?? []) {\n visitOne(ctor as unknown as Record<string, unknown>, member, klass.className);\n }\n }\n }\n\n private traced(\n original: AnyMethod,\n moduleName: string,\n className: string | undefined,\n target: MethodTarget,\n ): AnyMethod {\n // The patch must stay a `function` so the wrapped method keeps its call-site\n // receiver, which leaves `this` taken — same as instrumentation-pg does.\n // oxlint-disable-next-line typescript/no-this-alias -- see above\n const instrumentation = this;\n const defaultSpanName = `${className ? `${className}.` : \"\"}${target.name}`;\n\n return function patched(this: unknown, ...args: unknown[]): unknown {\n const config = instrumentation.getConfig();\n if (config.requireParentSpan && trace.getActiveSpan() === undefined) {\n return original.apply(this, args);\n }\n\n const attributes: Attributes = {\n [ATTR_IDOS_SDK_PACKAGE]: moduleName,\n [ATTR_IDOS_SDK_METHOD]: target.name,\n ...(className ? { [ATTR_IDOS_SDK_CLASS]: className } : {}),\n ...target.attributes?.(args),\n };\n\n const spanName = target.spanName?.(args) ?? defaultSpanName;\n const spanOptions = { kind: target.kind ?? SpanKind.INTERNAL, attributes };\n\n return instrumentation.tracer.startActiveSpan(spanName, spanOptions, (span) => {\n instrumentation._runSpanCustomizationHook(config.requestHook, \"requestHook\", span, {\n moduleName,\n className,\n methodName: target.name,\n args,\n });\n\n let result: unknown;\n try {\n result = original.apply(this, args);\n } catch (error) {\n instrumentation.failSpan(span, error);\n throw error;\n }\n\n if (!isThenable(result)) {\n instrumentation.endSpan(span, moduleName, className, target, result);\n return result;\n }\n\n return result.then(\n (value: unknown) => {\n instrumentation.endSpan(span, moduleName, className, target, value);\n return value;\n },\n (error: unknown) => {\n instrumentation.failSpan(span, error);\n throw error;\n },\n );\n });\n };\n }\n\n private endSpan(\n span: Span,\n moduleName: string,\n className: string | undefined,\n target: MethodTarget,\n result: unknown,\n ): void {\n const attributes = target.responseAttributes?.(result);\n if (attributes) span.setAttributes(attributes);\n\n this._runSpanCustomizationHook(this.getConfig().responseHook, \"responseHook\", span, {\n moduleName,\n className,\n methodName: target.name,\n result,\n });\n span.end();\n }\n\n private failSpan(span: Span, error: unknown): void {\n if (error instanceof Error) {\n span.recordException(error);\n span.setAttribute(ATTR_ERROR_TYPE, error.name);\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });\n } else {\n span.setAttribute(ATTR_ERROR_TYPE, typeof error);\n span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });\n }\n span.end();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/semconv.ts","../src/targets.ts","../src/version.ts","../src/instrumentation.ts"],"sourcesContent":["/**\n * Attributes emitted by this instrumentation that have no stable OpenTelemetry\n * semantic convention. Stable ones (`db.*`, `error.type`) are imported from\n * `@opentelemetry/semantic-conventions` at the call site.\n */\n\n/** Package the traced method lives in, e.g. `@idos-network/issuer`. */\nexport const ATTR_IDOS_SDK_PACKAGE = \"idos.sdk.package\";\n\n/** Class the traced method lives on, e.g. `idOSIssuer`. */\nexport const ATTR_IDOS_SDK_CLASS = \"idos.sdk.class\";\n\n/** Traced method name, e.g. `createUserProfile`. */\nexport const ATTR_IDOS_SDK_METHOD = \"idos.sdk.method\";\n\n/** `db.system.name` value for the idOS kwil network. */\nexport const IDOS_KWIL_SYSTEM = \"kwil\";\n\n/** Kwil namespace every idOS action runs against. */\nexport const IDOS_KWIL_NAMESPACE = \"main\";\n\n/** Transaction hash returned by a kwil `execute`. */\nexport const ATTR_IDOS_KWIL_TX_HASH = \"idos.kwil.tx_hash\";\n\n/** Whether a kwil `execute` waited for the transaction to be mined. */\nexport const ATTR_IDOS_KWIL_SYNCHRONOUS = \"idos.kwil.synchronous\";\n","import type { Attributes } from \"@opentelemetry/api\";\n\nimport { SpanKind } from \"@opentelemetry/api\";\nimport {\n ATTR_DB_NAMESPACE,\n ATTR_DB_OPERATION_NAME,\n ATTR_DB_SYSTEM_NAME,\n} from \"@opentelemetry/semantic-conventions\";\n\nimport {\n ATTR_IDOS_KWIL_SYNCHRONOUS,\n ATTR_IDOS_KWIL_TX_HASH,\n IDOS_KWIL_NAMESPACE,\n IDOS_KWIL_SYSTEM,\n} from \"./semconv\";\n\n/** A method to wrap. A bare string uses every default. */\nexport type MethodTarget = {\n name: string;\n /** Span name. Defaults to `<Class>.<method>`, or `<method>` for a function export. */\n spanName?: (args: readonly unknown[]) => string;\n /** Attributes derived from the arguments. Must not emit personal data. */\n attributes?: (args: readonly unknown[]) => Attributes;\n /** Attributes derived from the resolved value. Must not emit personal data. */\n responseAttributes?: (result: unknown) => Attributes;\n /** @default SpanKind.INTERNAL */\n kind?: SpanKind;\n};\n\nexport type ClassTarget = {\n /** Name of the class as exported by the module. */\n className: string;\n /** Instance methods, wrapped on the prototype. */\n methods: (string | MethodTarget)[];\n /** Static methods, wrapped on the constructor (`init`-style factories). */\n staticMethods?: (string | MethodTarget)[];\n};\n\nexport type ModuleTarget = {\n /** Module specifier. */\n name: string;\n supportedVersions: string[];\n /**\n * Only classes. Every method lives on a prototype or a constructor, both of\n * which are ordinary mutable objects — that is what lets\n * {@link IdosInstrumentation.patchModuleExports} work without a loader hook.\n * A bare function export would sit on the sealed module namespace instead,\n * and could only be reached via `import-in-the-middle`.\n */\n classes: ClassTarget[];\n};\n\nconst SUPPORTED = [\">=2.0.0 <3\"];\nconst MM_OPERATOR_SUPPORTED = [\">=0.1.0 <1\"];\n\n/**\n * Kwil `call`/`execute` are the idOS equivalent of `pg.Client.query`: every SDK\n * operation bottoms out here. The action name is a fixed identifier from the\n * action schema, so it is safe to record; the inputs are not.\n */\nconst kwilAttributes = (args: readonly unknown[]): Attributes => {\n const params = args[0] as { name?: unknown } | undefined;\n return {\n [ATTR_DB_SYSTEM_NAME]: IDOS_KWIL_SYSTEM,\n [ATTR_DB_NAMESPACE]: IDOS_KWIL_NAMESPACE,\n ...(typeof params?.name === \"string\" ? { [ATTR_DB_OPERATION_NAME]: params.name } : {}),\n };\n};\n\nconst kwilSpanName =\n (operation: string) =>\n (args: readonly unknown[]): string => {\n const params = args[0] as { name?: unknown } | undefined;\n return typeof params?.name === \"string\"\n ? `idos.kwil.${operation} ${params.name}`\n : `idos.kwil.${operation}`;\n };\n\n/** Methods shared by every logged-out-capable client state. */\nconst CLIENT_LOGGED_IN_METHODS = [\n \"requestDWGMessage\",\n \"createCredential\",\n \"removeCredential\",\n \"getCredentialById\",\n \"shareCredential\",\n \"getAllCredentials\",\n \"getAccessGrantsOwned\",\n \"getAttributes\",\n \"createAttribute\",\n \"getCredentialContentSha256Hash\",\n \"getCredentialContent\",\n \"getCredentialWithEncryptedContent\",\n \"getCredentialSharedContent\",\n \"getGrants\",\n \"getGrantsCount\",\n \"getCredentialShared\",\n \"revokeAccessGrant\",\n \"addWallet\",\n \"addWallets\",\n \"getWallets\",\n \"removeWallet\",\n \"removeWallets\",\n \"filterCredentials\",\n \"requestAccessGrant\",\n \"logOut\",\n];\n\nexport const TARGETS: ModuleTarget[] = [\n {\n name: \"@idos-network/kwil-infra\",\n supportedVersions: SUPPORTED,\n classes: [\n {\n className: \"KwilActionClient\",\n methods: [\n {\n name: \"call\",\n kind: SpanKind.CLIENT,\n spanName: kwilSpanName(\"call\"),\n attributes: kwilAttributes,\n },\n {\n name: \"execute\",\n kind: SpanKind.CLIENT,\n spanName: kwilSpanName(\"execute\"),\n attributes: (args) => ({\n ...kwilAttributes(args),\n // `synchronous` defaults to true and also decides whether the span\n // covers the tx-confirmation polling loop.\n [ATTR_IDOS_KWIL_SYNCHRONOUS]: args[2] === undefined ? true : Boolean(args[2]),\n }),\n responseAttributes: (result) =>\n typeof result === \"string\" ? { [ATTR_IDOS_KWIL_TX_HASH]: result } : {},\n },\n {\n // Usually the bulk of an `execute`: polling the node until the tx is\n // mined. A tx hash is a public chain identifier, so it is safe to record.\n name: \"waitForTx\",\n kind: SpanKind.CLIENT,\n spanName: () => \"idos.kwil.waitForTx\",\n attributes: (args) => ({\n [ATTR_DB_SYSTEM_NAME]: IDOS_KWIL_SYSTEM,\n [ATTR_DB_NAMESPACE]: IDOS_KWIL_NAMESPACE,\n ...(typeof args[0] === \"string\" ? { [ATTR_IDOS_KWIL_TX_HASH]: args[0] } : {}),\n }),\n },\n ],\n },\n ],\n },\n {\n name: \"@idos-network/client\",\n supportedVersions: SUPPORTED,\n classes: [\n { className: \"idOSClientConfiguration\", methods: [\"createClient\"] },\n {\n className: \"idOSClientIdle\",\n methods: [\"addressHasProfile\", \"withUserSigner\", \"logOut\"],\n staticMethods: [\"fromConfig\"],\n },\n {\n className: \"idOSClientWithUserSigner\",\n methods: [\"hasProfile\", \"createUserEncryptionProfile\", \"logIn\", \"logOut\"],\n },\n { className: \"idOSClientLoggedIn\", methods: CLIENT_LOGGED_IN_METHODS },\n ],\n },\n {\n name: \"@idos-network/issuer\",\n supportedVersions: SUPPORTED,\n classes: [\n {\n className: \"idOSIssuer\",\n staticMethods: [\"init\"],\n methods: [\n \"hasProfile\",\n \"createUserProfile\",\n \"upsertWalletAsInserter\",\n \"createUser\",\n \"getUser\",\n \"requestDelegatedWriteGrantMessage\",\n \"createCredentialByDelegatedWriteGrant\",\n \"editCredentialAsIssuer\",\n \"getCredentialIdByContentHash\",\n \"getCredentialShared\",\n ],\n },\n ],\n },\n {\n name: \"@idos-network/mm-operator\",\n supportedVersions: MM_OPERATOR_SUPPORTED,\n classes: [\n {\n // Arguments carry user ids and storage tokens: no attributes.\n className: \"idOSMmOperator\",\n staticMethods: [\"init\"],\n methods: [\n \"getUser\",\n \"createUser\",\n \"getCredentials\",\n \"createCredential\",\n \"getCredentialContent\",\n \"requestUserWipe\",\n \"wipeUser\",\n ],\n },\n ],\n },\n {\n name: \"@idos-network/consumer\",\n supportedVersions: SUPPORTED,\n classes: [\n {\n className: \"idOSConsumer\",\n staticMethods: [\"init\"],\n methods: [\n \"getCredentialSharedFromIDOS\",\n \"getCredentialSharedContentDecrypted\",\n \"rescindSharedCredential\",\n \"getGrantsCount\",\n \"getAccessGrantsForCredential\",\n \"getCredentialsSharedByUser\",\n \"getAccessGrants\",\n \"verifyCredential\",\n ],\n },\n ],\n },\n];\n","// Keep in sync with package.json — it is the `otel.scope.version` of every emitted span.\nexport const PACKAGE_NAME = \"@idos-network/instrumentation\";\nexport const PACKAGE_VERSION = \"2.0.1\";\n","import type { Attributes, Span } from \"@opentelemetry/api\";\n\nimport { SpanKind, SpanStatusCode, trace } from \"@opentelemetry/api\";\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n isWrapped,\n} from \"@opentelemetry/instrumentation\";\nimport { ATTR_ERROR_TYPE } from \"@opentelemetry/semantic-conventions\";\n\nimport type { MethodTarget, ModuleTarget } from \"./targets\";\nimport type { IdosInstrumentationConfig } from \"./types\";\n\nimport { ATTR_IDOS_SDK_CLASS, ATTR_IDOS_SDK_METHOD, ATTR_IDOS_SDK_PACKAGE } from \"./semconv\";\nimport { TARGETS } from \"./targets\";\nimport { PACKAGE_NAME, PACKAGE_VERSION } from \"./version\";\n\ntype AnyMethod = (...args: unknown[]) => unknown;\n\nconst isThenable = (value: unknown): value is PromiseLike<unknown> =>\n typeof (value as PromiseLike<unknown> | null)?.then === \"function\";\n\n/**\n * Traces the idOS SDK: every public method of `@idos-network/client`,\n * `/consumer`, `/issuer`, the enclave providers, `verifyCredential`, and the\n * kwil `call`/`execute` round-trips they all bottom out in.\n */\nexport class IdosInstrumentation extends InstrumentationBase<IdosInstrumentationConfig> {\n constructor(config: IdosInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n }\n\n protected init(): InstrumentationNodeModuleDefinition[] {\n return TARGETS.map(\n (target) =>\n new InstrumentationNodeModuleDefinition(\n target.name,\n target.supportedVersions,\n (moduleExports: unknown) => this.applyPatch(target.name, target, moduleExports),\n (moduleExports: unknown) => this.removePatch(target.name, target, moduleExports),\n ),\n );\n }\n\n /**\n * Patch a module namespace you already imported.\n *\n * The automatic hooking in {@link InstrumentationBase} needs Node's module\n * loader hook (`import-in-the-middle`), which has to be installed with\n * `module.register()` before the import — and does not exist at all in a\n * browser or a bundled app. This is the alternative everywhere: import the\n * idOS module and hand its namespace over. Exports the module does not have\n * are skipped.\n */\n patchModuleExports(moduleName: string, moduleExports: unknown): void {\n const target = this.findTarget(moduleName);\n if (target) this.applyPatch(moduleName, target, moduleExports);\n }\n\n /** Reverse of {@link patchModuleExports}. */\n unpatchModuleExports(moduleName: string, moduleExports: unknown): void {\n const target = this.findTarget(moduleName);\n if (target) this.removePatch(moduleName, target, moduleExports);\n }\n\n private findTarget(moduleName: string): ModuleTarget | undefined {\n const target = TARGETS.find((t) => t.name === moduleName);\n if (!target) this._diag.warn(`No instrumentation targets known for \"${moduleName}\"`);\n return target;\n }\n\n private applyPatch(moduleName: string, target: ModuleTarget, moduleExports: unknown): unknown {\n this.eachMember(moduleName, target, moduleExports, (owner, name, method, className) => {\n if (isWrapped(owner[name])) this._unwrap(owner, name);\n this._wrap(owner, name, (original) =>\n this.traced(original as AnyMethod, moduleName, className, method),\n );\n });\n return moduleExports;\n }\n\n private removePatch(moduleName: string, target: ModuleTarget, moduleExports: unknown): unknown {\n this.eachMember(moduleName, target, moduleExports, (owner, name) => {\n if (isWrapped(owner[name])) this._unwrap(owner, name);\n });\n return moduleExports;\n }\n\n /** Resolves every target method to the object that owns it, skipping what is absent. */\n private eachMember(\n moduleName: string,\n target: ModuleTarget,\n moduleExports: unknown,\n visit: (\n owner: Record<string, unknown>,\n name: string,\n method: MethodTarget,\n className: string | undefined,\n ) => void,\n ): void {\n if (typeof moduleExports !== \"object\" || moduleExports === null) return;\n const namespace = moduleExports as Record<string, unknown>;\n\n const visitOne = (\n owner: Record<string, unknown>,\n member: string | MethodTarget,\n className: string | undefined,\n ): void => {\n const method: MethodTarget = typeof member === \"string\" ? { name: member } : member;\n const label = `${className ? `${className}.` : \"\"}${method.name}`;\n if (typeof owner[method.name] !== \"function\") {\n this._diag.debug(`${moduleName}: ${label} is not a function, skipping`);\n return;\n }\n try {\n visit(owner, method.name, method, className);\n } catch (error) {\n // An ESM namespace object is read-only unless an import hook made it writable.\n this._diag.warn(`${moduleName}: could not patch ${label}: ${String(error)}`);\n }\n };\n\n for (const klass of target.classes) {\n const ctor = namespace[klass.className];\n if (typeof ctor !== \"function\") {\n this._diag.debug(`${moduleName}: class ${klass.className} not exported, skipping`);\n continue;\n }\n const prototype = (ctor as { prototype?: unknown }).prototype;\n if (typeof prototype === \"object\" && prototype !== null) {\n for (const member of klass.methods) {\n visitOne(prototype as Record<string, unknown>, member, klass.className);\n }\n }\n for (const member of klass.staticMethods ?? []) {\n visitOne(ctor as unknown as Record<string, unknown>, member, klass.className);\n }\n }\n }\n\n private traced(\n original: AnyMethod,\n moduleName: string,\n className: string | undefined,\n target: MethodTarget,\n ): AnyMethod {\n // The patch must stay a `function` so the wrapped method keeps its call-site\n // receiver, which leaves `this` taken — same as instrumentation-pg does.\n // oxlint-disable-next-line typescript/no-this-alias -- see above\n const instrumentation = this;\n const defaultSpanName = `${className ? `${className}.` : \"\"}${target.name}`;\n\n return function patched(this: unknown, ...args: unknown[]): unknown {\n const config = instrumentation.getConfig();\n if (config.requireParentSpan && trace.getActiveSpan() === undefined) {\n return original.apply(this, args);\n }\n\n const attributes: Attributes = {\n [ATTR_IDOS_SDK_PACKAGE]: moduleName,\n [ATTR_IDOS_SDK_METHOD]: target.name,\n ...(className ? { [ATTR_IDOS_SDK_CLASS]: className } : {}),\n ...target.attributes?.(args),\n };\n\n const spanName = target.spanName?.(args) ?? defaultSpanName;\n const spanOptions = { kind: target.kind ?? SpanKind.INTERNAL, attributes };\n\n return instrumentation.tracer.startActiveSpan(spanName, spanOptions, (span) => {\n instrumentation._runSpanCustomizationHook(config.requestHook, \"requestHook\", span, {\n moduleName,\n className,\n methodName: target.name,\n args,\n });\n\n let result: unknown;\n try {\n result = original.apply(this, args);\n } catch (error) {\n instrumentation.failSpan(span, error);\n throw error;\n }\n\n if (!isThenable(result)) {\n instrumentation.endSpan(span, moduleName, className, target, result);\n return result;\n }\n\n return result.then(\n (value: unknown) => {\n instrumentation.endSpan(span, moduleName, className, target, value);\n return value;\n },\n (error: unknown) => {\n instrumentation.failSpan(span, error);\n throw error;\n },\n );\n });\n };\n }\n\n private endSpan(\n span: Span,\n moduleName: string,\n className: string | undefined,\n target: MethodTarget,\n result: unknown,\n ): void {\n const attributes = target.responseAttributes?.(result);\n if (attributes) span.setAttributes(attributes);\n\n this._runSpanCustomizationHook(this.getConfig().responseHook, \"responseHook\", span, {\n moduleName,\n className,\n methodName: target.name,\n result,\n });\n span.end();\n }\n\n private failSpan(span: Span, error: unknown): void {\n if (error instanceof Error) {\n span.recordException(error);\n span.setAttribute(ATTR_ERROR_TYPE, error.name);\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });\n } else {\n span.setAttribute(ATTR_ERROR_TYPE, typeof error);\n span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });\n }\n span.end();\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idos-network/instrumentation",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "OpenTelemetry instrumentation for the idOS JavaScript SDK",
5
5
  "keywords": [
6
6
  "idos",
@@ -39,10 +39,11 @@
39
39
  "@opentelemetry/semantic-conventions": "^1.43.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@idos-network/client": "3.0.0",
43
- "@idos-network/consumer": "3.0.0",
44
- "@idos-network/issuer": "3.0.0",
45
- "@idos-network/kwil-infra": "3.0.0",
42
+ "@idos-network/client": "5.0.0",
43
+ "@idos-network/consumer": "5.0.0",
44
+ "@idos-network/issuer": "5.0.0",
45
+ "@idos-network/kwil-infra": "5.0.0",
46
+ "@idos-network/mm-operator": "0.1.0",
46
47
  "@opentelemetry/api": "^1.10.0",
47
48
  "@opentelemetry/context-async-hooks": "^3.0.0",
48
49
  "@opentelemetry/sdk-trace": "^3.0.0",
@@ -55,10 +55,35 @@ const buildNamespaces = () => {
55
55
  }
56
56
  }
57
57
 
58
+ class idOSMmOperator {
59
+ static async init(): Promise<idOSMmOperator> {
60
+ return new idOSMmOperator();
61
+ }
62
+
63
+ async getUser(storageToken: string): Promise<{ id: string }> {
64
+ await kwil.call({ name: "get_user_as_mm_operator", inputs: { storage_token: storageToken } });
65
+ return { id: "u1" };
66
+ }
67
+
68
+ async createUser(_params: { storageToken: string }): Promise<void> {}
69
+ async getCredentials(_params: { storageToken: string }): Promise<[]> {
70
+ return [];
71
+ }
72
+ async createCredential(_params: { storageToken: string }): Promise<{ id: string }> {
73
+ return { id: "c1" };
74
+ }
75
+ async getCredentialContent(_params: { storageToken: string }): Promise<string> {
76
+ return "content";
77
+ }
78
+ async requestUserWipe(_params: { deleteToken: string }): Promise<void> {}
79
+ async wipeUser(_params: { deleteToken: string }): Promise<void> {}
80
+ }
81
+
58
82
  return {
59
83
  kwil,
60
84
  kwilInfra: { KwilActionClient },
61
85
  issuer: { idOSIssuer },
86
+ mmOperator: { idOSMmOperator },
62
87
  };
63
88
  };
64
89
 
@@ -157,6 +182,39 @@ describe("IdosInstrumentation", () => {
157
182
  expect(child.parentSpanContext?.spanId).toBe(parent.spanContext().spanId);
158
183
  });
159
184
 
185
+ it("traces idOSMmOperator.init and every operator method without their arguments", async () => {
186
+ instrumentation.patchModuleExports("@idos-network/mm-operator", namespaces.mmOperator);
187
+ const token = "secret-storage-token";
188
+
189
+ const operator = await namespaces.mmOperator.idOSMmOperator.init();
190
+ await operator.getUser(token);
191
+ await operator.createUser({ storageToken: token });
192
+ await operator.getCredentials({ storageToken: token });
193
+ await operator.createCredential({ storageToken: token });
194
+ await operator.getCredentialContent({ storageToken: token });
195
+ await operator.requestUserWipe({ deleteToken: token });
196
+ await operator.wipeUser({ deleteToken: token });
197
+
198
+ const methods = [
199
+ "init",
200
+ "getUser",
201
+ "createUser",
202
+ "getCredentials",
203
+ "createCredential",
204
+ "getCredentialContent",
205
+ "requestUserWipe",
206
+ "wipeUser",
207
+ ];
208
+ expect(finished().map((span) => span.name)).toEqual(
209
+ methods.map((method) => `idOSMmOperator.${method}`),
210
+ );
211
+ for (const [index, span] of finished().entries()) {
212
+ expect(span.attributes[ATTR_IDOS_SDK_CLASS]).toBe("idOSMmOperator");
213
+ expect(span.attributes[ATTR_IDOS_SDK_METHOD]).toBe(methods[index]);
214
+ expect(JSON.stringify(span.attributes)).not.toContain(token);
215
+ }
216
+ });
217
+
160
218
  it("skips instrumentation when requireParentSpan is set and there is no parent", async () => {
161
219
  instrumentation.setConfig({ requireParentSpan: true });
162
220
  instrumentation.patchModuleExports("@idos-network/kwil-infra", namespaces.kwilInfra);
package/src/targets.ts CHANGED
@@ -51,6 +51,7 @@ export type ModuleTarget = {
51
51
  };
52
52
 
53
53
  const SUPPORTED = [">=2.0.0 <3"];
54
+ const MM_OPERATOR_SUPPORTED = [">=0.1.0 <1"];
54
55
 
55
56
  /**
56
57
  * Kwil `call`/`execute` are the idOS equivalent of `pg.Client.query`: every SDK
@@ -186,6 +187,26 @@ export const TARGETS: ModuleTarget[] = [
186
187
  },
187
188
  ],
188
189
  },
190
+ {
191
+ name: "@idos-network/mm-operator",
192
+ supportedVersions: MM_OPERATOR_SUPPORTED,
193
+ classes: [
194
+ {
195
+ // Arguments carry user ids and storage tokens: no attributes.
196
+ className: "idOSMmOperator",
197
+ staticMethods: ["init"],
198
+ methods: [
199
+ "getUser",
200
+ "createUser",
201
+ "getCredentials",
202
+ "createCredential",
203
+ "getCredentialContent",
204
+ "requestUserWipe",
205
+ "wipeUser",
206
+ ],
207
+ },
208
+ ],
209
+ },
189
210
  {
190
211
  name: "@idos-network/consumer",
191
212
  supportedVersions: SUPPORTED,