All files / src/lib sparql.ts

91.89% Statements 34/37
88.89% Branches 16/18
100% Functions 7/7
91.43% Lines 32/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75            2x 3x 3x             8x     8x 8x       8x 8x   8x 9x   9x   9x 1x 8x 2x 6x 2x 2x   4x         4x 4x 3x 3x   1x   4x           9x     8x   8x 2x         6x       1x 8x  
import { Term } from 'rdf-js'
import { prefixes as knownPrefixes, shrink } from '@zazuko/rdf-vocabularies'
 
type Value = SparqlTemplateResult | Term | string | null | undefined
 
function prefixDeclarations(prefixes: Set<string>): string {
  return [...prefixes]
    .filter(prefix => prefix in knownPrefixes)
    .map(prefix => `PREFIX ${prefix}: <${knownPrefixes[prefix]}>`)
    .join('\n')
}
 
export class SparqlTemplateResult {
  readonly strings: TemplateStringsArray;
  readonly values: readonly Value[];
  readonly prefixes: Set<string> = new Set()
 
  constructor(strings: TemplateStringsArray, values: Value[]) {
    this.strings = strings
    this.values = values
  }
 
  public toString({ prefixes } = { prefixes: true }): string {
    const l = this.strings.length - 1
    let query = ''
 
    for (let i = 0; i < l; i++) {
      const s = this.strings[i]
 
      const value = this.values[i]
      let valueStr: string
      if (typeof value === 'string') {
        valueStr = `"${value}"`
      } else if (typeof value === 'undefined' || value === null) {
        valueStr = ''
      } else if (value instanceof SparqlTemplateResult) {
        valueStr = value.toString({ prefixes: false })
        value.prefixes.forEach(prefix => this.prefixes.add(prefix))
      } else {
        switch (value.termType) {
          case 'Literal':
            valueStr = `"${value.value}"`
            break
          case 'NamedNode': {
            const shrunk = shrink(value.value)
            if (shrunk) {
              this.prefixes.add(shrunk.split(':')[0])
              valueStr = shrunk
            } else {
              valueStr = `<${value.value}>`
            }
          } break
          default:
            valueStr = value.value
        }
      }
 
      query += s + valueStr
    }
 
    query += this.strings[l]
 
    if (prefixes && this.prefixes.size > 0) {
      return `${prefixDeclarations(this.prefixes)}
 
${query}`
    }
 
    return query
  }
}
 
export const sparql = (strings: TemplateStringsArray, ...values: Value[]) =>
  new SparqlTemplateResult(strings, values)