Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
Merge 83fbeef into f66ab61
Browse files Browse the repository at this point in the history
  • Loading branch information
totorogendut committed Apr 17, 2020
2 parents f66ab61 + 83fbeef commit 892480d
Show file tree
Hide file tree
Showing 28 changed files with 310 additions and 139 deletions.
2 changes: 2 additions & 0 deletions .prettierignore
@@ -0,0 +1,2 @@
README.md
RELEASE.md
7 changes: 6 additions & 1 deletion RELEASE.md
@@ -1,8 +1,13 @@
# Releases

## unrelased

- FEATURE: Server-side fund() now live.
- Errors now more readable.

## 0.1.0

- FEAT: Custom syntax with `<template fundme></template>` tags.
- FEATURE: Custom syntax with `<template fundme></template>` tags.

## 0.0.5

Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
@@ -1,5 +1,5 @@
module.exports = {
roots: ['<rootDir>/src'],
roots: ['<rootDir>/tests'],
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
Expand Down
44 changes: 27 additions & 17 deletions src/fund/errors.ts
@@ -1,29 +1,39 @@
import { DEFAULT_WEIGHT } from './set-pointer-multiple'

export const defaultAddressNotFound =
'Fundme.js: default address not found. Use setDefaultAddress(str: string) to set it first.'
export const invalidAddress = 'Fundme.js: Invalid Web Monetization pointer address is given.'
export const addressNotFound = 'Fundme.js: address not found.'
export const addressIsNotAString = 'Fundme.js: address must be a string.'
export const weightNotFound = 'Fundme.js: entries .weight not found.'
export function FundmeError(err: string): string {
return 'Fundme.js: ' + err
}

export const defaultAddressNotFound = 'default address not found. Use setDefaultAddress(str: string) to set it first.'
export const invalidAddress = 'Invalid Web Monetization pointer address is given.'
export const addressNotFound = 'address not found.'
export const addressIsNotAString = 'address must be a string.'
export const getCurrentPointerAddressMustClientSide = "can't use getCurrentPointerAddress() server-side."
export const weightNotFound = 'entries .weight not found.'
export function weightIsNotANumber(str: string) {
return `Fundme.js: ${str} has weight that is not a number. It has been set to ${DEFAULT_WEIGHT} (default).`
return `${str} has weight that is not a number. It has been set to ${DEFAULT_WEIGHT} (default).`
}

// about meta tag for Web Monetization API
export const metaTagNotFound = 'Fundme.js: web monetization meta tag is not found.'
export const metaTagNotFound = 'web monetization meta tag is not found.'
export const metaTagMultipleIsFound =
'Fundme.js: multiple <meta name="monetization" /> found - Web Monetization API only support a single meta tag.'
'multiple <meta name="monetization" /> found - Web Monetization API only support a single meta tag.'

// pointers template
export const noTemplateFound = 'Fundme.js: no monetization template is found.'
export const failParsingTemplate = 'Fundme.js: fails to parse address from <template data-fund></template>.'
export const noTemplateFound = 'no monetization template is found.'
export const failParsingTemplate = 'fails to parse address from <template data-fund></template>.'
export const templateSinglePointerHasWeight =
'Fundme.js: found single <template data-fund></template> but has weight - only address will be parsed.'
'found single <template data-fund></template> but has weight - only address will be parsed.'

// script json template
export const cannotParseScriptJson =
'Fundme.js: cannot parse JSON from <script fundme>. Make sure it contains a valid JSON.'
export const jsonTemplateIsInvalid = "Fundme.js: found <script fundme> but it's not valid."
export const scriptFundmeIsNotApplicationJson =
'Fundme.js: found <script fundme> but its type is not "application/json"'
export const cannotParseScriptJson = 'cannot parse JSON from <script fundme>. Make sure it contains a valid JSON.'
export const jsonTemplateIsInvalid = "found <script fundme> but it's not valid."
export const scriptFundmeIsNotApplicationJson = 'found <script fundme> but its type is not "application/json"'

/*****************************
* *
* Server-side fund() *
* *
*****************************/
export const noUndefinedFundOnServerSide = "can't use fund() with empty parameters in server side."
export const invalidFundmeServerSide = 'invalid fundme parameters on the server-side.'
3 changes: 3 additions & 0 deletions src/fund/global.d.ts
Expand Up @@ -6,8 +6,11 @@ interface WMPointer {
}

interface fundOptions {
force?: 'client' | 'server'
maxPool?: number
default?: boolean
affiliateId?: string
affiliateEntry?: boolean
}

// declare var document: any;
Expand Down
52 changes: 52 additions & 0 deletions src/fund/main-client.ts
@@ -0,0 +1,52 @@
import { isMultiplePointer } from './utils'
import { setPointerSingle } from './set-pointer-single'
import { setPointerFromTemplates } from './set-pointer-template'
import { setPointerMultiple } from './set-pointer-multiple'
import { defaultAddressNotFound, invalidAddress, FundmeError } from './errors'
import { defaultAddress, FundType, setFundType } from './main'

export function clientSideFund(pointer?: WMAddress, options: fundOptions = {}): FundType {
if (typeof pointer === 'string') {
if (pointer === 'default') {
if (defaultAddress !== undefined) {
if (typeof defaultAddress === 'string') {
setPointerSingle(defaultAddress, options)
} else {
setPointerMultiple(defaultAddress, options)
}
return setFundType(FundType.isDefault)
} else {
throw FundmeError(defaultAddressNotFound)
}
}
setPointerSingle(pointer, options)
return setFundType(FundType.isSingle)
}

if (isMultiplePointer(pointer)) {
setPointerMultiple(pointer, options)
return setFundType(FundType.isMultiple)
}

if (pointer === undefined) {
setPointerFromTemplates()
return setFundType(FundType.isFromTemplate)
}
throw FundmeError(invalidAddress)
}

let forceBrowser: boolean = false
export function forceFundmeOnBrowser() {
forceBrowser = true
}

export const isBrowser = (options: fundOptions = {}): boolean => {
if (options.force === 'server') return false

if (forceBrowser || options.force === 'client') {
forceBrowser = false
return true
}

return require === undefined && module === undefined
}
17 changes: 17 additions & 0 deletions src/fund/main-server.ts
@@ -0,0 +1,17 @@
import { setCurrentPointer } from './main'
import { isMultiplePointer } from './utils'
import { setPointerMultiple } from './set-pointer-multiple'
import { FundmeError, invalidFundmeServerSide } from './errors'

export function serverSideFund(pointer: WMAddress): string {
if (typeof pointer === 'string') {
setCurrentPointer(pointer)
return pointer
}

if (isMultiplePointer(pointer)) {
return setPointerMultiple(pointer)
}

throw FundmeError(invalidFundmeServerSide)
}
72 changes: 33 additions & 39 deletions src/fund/main.ts
@@ -1,8 +1,13 @@
import { isMultiplePointer } from './utils'
import { setPointerSingle } from './set-pointer-single'
import { setPointerMultiple, createPool } from './set-pointer-multiple'
import { setPointerFromTemplates } from './set-pointer-template'
import { defaultAddressNotFound, invalidAddress, metaTagNotFound, metaTagMultipleIsFound } from './errors'
import { createPool } from './set-pointer-multiple'
import {
metaTagNotFound,
metaTagMultipleIsFound,
noUndefinedFundOnServerSide,
getCurrentPointerAddressMustClientSide,
FundmeError,
} from './errors'
import { clientSideFund, isBrowser, forceFundmeOnBrowser } from './main-client'
import { serverSideFund } from './main-server'

export let defaultAddress: WMAddress
export let currentPointer: WMAddress
Expand All @@ -16,34 +21,16 @@ export enum FundType {
isUndefined = 'undefined',
}

export function fund(pointer?: WMAddress, options?: fundOptions): FundType {
if (typeof pointer === 'string') {
if (pointer === 'default') {
if (defaultAddress !== undefined) {
if (typeof defaultAddress === 'string') {
setPointerSingle(defaultAddress)
} else {
setPointerMultiple(defaultAddress)
}
return setFundType(FundType.isDefault)
} else {
throw new Error(defaultAddressNotFound)
}
export function fund(pointer?: WMAddress, options: fundOptions = {}): FundType | string {
if (isBrowser(options)) {
return clientSideFund(pointer, options)
} else {
if (pointer === undefined) {
throw FundmeError(noUndefinedFundOnServerSide)
} else {
return serverSideFund(pointer)
}
setPointerSingle(pointer)
return setFundType(FundType.isSingle)
}

if (isMultiplePointer(pointer)) {
setPointerMultiple(pointer)
return setFundType(FundType.isMultiple)
}

if (pointer === undefined) {
setPointerFromTemplates()
return setFundType(FundType.isFromTemplate)
}
throw new Error(invalidAddress)
}

export function setDefaultAddress(address: WMAddress): void {
Expand All @@ -65,17 +52,22 @@ export function setFundType(type: FundType): FundType {
}

export function getCurrentPointerAddress(): string {
const metaTag: NodeListOf<HTMLMetaElement> = document.head.querySelectorAll('meta[name="monetization"]')
// const forced = forceBrowser
if (isBrowser()) {
const metaTag: NodeListOf<HTMLMetaElement> = document.head.querySelectorAll('meta[name="monetization"]')

if (metaTag.length > 1) {
throw new Error(metaTagMultipleIsFound)
}
if (metaTag.length > 1) {
throw FundmeError(metaTagMultipleIsFound)
}

if (metaTag[0]) {
return metaTag[0].content
if (metaTag[0]) {
return metaTag[0].content
}
throw FundmeError(metaTagNotFound)
} else {
if (currentPointer) return currentPointer.toString()
throw FundmeError(getCurrentPointerAddressMustClientSide)
}

throw new Error(metaTagNotFound)
}

export function getCurrentPointerPool(): Array<string | WMPointer> {
Expand All @@ -91,3 +83,5 @@ export function convertToPointerPool(pointer: WMAddress): Array<string | WMPoint

return pointer
}

export { isBrowser, forceFundmeOnBrowser }
19 changes: 12 additions & 7 deletions src/fund/set-pointer-multiple.ts
@@ -1,24 +1,29 @@
import { getWinningPointer, setWebMonetizationPointer, getPoolWeightSum } from './utils'
import { addressNotFound, addressIsNotAString, weightIsNotANumber } from './errors'
import { setCurrentPointer } from './main'
import { addressNotFound, addressIsNotAString, weightIsNotANumber, FundmeError } from './errors'
import { setCurrentPointer, isBrowser } from './main'

export const DEFAULT_WEIGHT: number = 5

// TODO check pointer.address with RegEx
export function setPointerMultiple(pointers: Array<string | WMPointer>): void {
export function setPointerMultiple(pointers: Array<string | WMPointer>, options: fundOptions = {}): string {
const pool = createPool(pointers)
const pickedPointer = pickPointer(pool)
const pointerAddress = getPointerAddress(pickedPointer)
setCurrentPointer(pool)
setWebMonetizationPointer(getPointerAddress(pickedPointer))
if (isBrowser(options)) {
setWebMonetizationPointer(pointerAddress)
}

return pointerAddress
}

export function getPointerAddress(pointer: WMPointer): string {
const address = pointer.address

if (!address) {
throw new Error(addressNotFound)
throw FundmeError(addressNotFound)
} else if (typeof address !== 'string') {
throw new Error(addressIsNotAString)
throw FundmeError(addressIsNotAString)
}
return address
}
Expand All @@ -27,7 +32,7 @@ export function createPool(pointers: Array<string | WMPointer>): WMPointer[] {
return pointers.map((pointer) => {
let wmPointer: WMPointer
if (typeof pointer === 'string') pointer = convertToPointer(pointer)
if (!('address' in pointer)) throw new Error(addressNotFound)
if (!('address' in pointer)) throw FundmeError(addressNotFound)
wmPointer = checkWeight(pointer)

return wmPointer
Expand Down
8 changes: 5 additions & 3 deletions src/fund/set-pointer-single.ts
@@ -1,7 +1,9 @@
import { setWebMonetizationPointer } from './utils'
import { setCurrentPointer } from './main'
import { setCurrentPointer, isBrowser } from './main'

export function setPointerSingle(pointer: string): void {
export function setPointerSingle(pointer: string, options: fundOptions = {}): void {
setCurrentPointer(pointer)
setWebMonetizationPointer(pointer)
if (isBrowser(options)) {
setWebMonetizationPointer(pointer)
}
}
15 changes: 8 additions & 7 deletions src/fund/set-pointer-template.ts
Expand Up @@ -5,6 +5,7 @@ import {
scriptFundmeIsNotApplicationJson,
cannotParseScriptJson,
jsonTemplateIsInvalid,
FundmeError,
} from './errors'

export const FUNDME_TEMPLATE_SELECTOR = 'template[data-fund]'
Expand All @@ -13,13 +14,13 @@ export const FUNDME_JSON_SELECTOR = 'script[fundme]'

type JSONTemplate = Array<WMPointer | string>

export function setPointerFromTemplates(): void {
export function setPointerFromTemplates(options: fundOptions = {}): void {
const pointers: Array<WMPointer> = [...scrapeTemplate(), ...scrapeJson(), ...scrapeCustomSyntax()]

if (pointers.length) {
setPointerMultiple(pointers)
setPointerMultiple(pointers, options)
} else {
throw new Error(noTemplateFound)
throw FundmeError(noTemplateFound)
}
}

Expand All @@ -45,19 +46,19 @@ function parseScriptJson(json: HTMLScriptElement): WMPointer[] {
try {
parsed = JSON.parse(json.innerHTML)
} catch (err) {
throw new Error(cannotParseScriptJson)
throw FundmeError(cannotParseScriptJson)
}

if (json.type !== 'application/json') {
throw new Error(scriptFundmeIsNotApplicationJson)
throw FundmeError(scriptFundmeIsNotApplicationJson)
}

if (Array.isArray(parsed)) {
pointers = createPool(parsed)
} else if (typeof parsed === 'string') {
pointers = createPool([parsed])
} else {
throw new Error(jsonTemplateIsInvalid)
throw FundmeError(jsonTemplateIsInvalid)
}

return pointers
Expand All @@ -83,7 +84,7 @@ export function parseTemplate(template: HTMLTemplateElement): WMPointer {
template.dataset.fundWeight !== undefined ? parseInt(template.dataset.fundWeight, 0) : DEFAULT_WEIGHT

if (!address) {
throw new Error(failParsingTemplate)
throw FundmeError(failParsingTemplate)
}

const pointer: WMPointer = checkWeight({
Expand Down
2 changes: 0 additions & 2 deletions src/fund/utils.ts
@@ -1,5 +1,3 @@
import { currentPointer } from './main'

export function isMultiplePointer(s: any): boolean {
return Array.isArray(s)
}
Expand Down

0 comments on commit 892480d

Please sign in to comment.