Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
Acker Apple committed Apr 5, 2024
1 parent ac39b91 commit f94d748
Show file tree
Hide file tree
Showing 16 changed files with 1,818 additions and 9,407 deletions.
10,705 changes: 1,524 additions & 9,181 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
"crypto-js": "^4.1.1",
"express": "^4.18.2",
"form-urlencoded": "^6.1.0",
"stripe-angular": "^1.9.3"
"stripe-angular": "^1.9.3",
"taggedjs": "github:ackerapple/taggedjs",
"taggedjs-dump": "github:ackerapple/taggedjs-dump",
"taggedjs-gateway": "github:ackerapple/taggedjs-gateway"
}
}
5 changes: 3 additions & 2 deletions src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NgModule } from "@angular/core"
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core"
import { BrowserModule } from "@angular/platform-browser"

import { AppComponent } from "./components/app.component"
Expand All @@ -15,5 +15,6 @@ import { AckModule } from 'ack-angular'
StripeModule.forRoot()
],
declarations,
bootstrap:[ AppComponent ]
bootstrap:[ AppComponent ],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
}) export class AppModule {}
2 changes: 1 addition & 1 deletion src/components/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -789,4 +789,4 @@ function findGroupAndApiByName(

return {group, api, level}
}
}
}
18 changes: 1 addition & 17 deletions src/components/app.component.utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ISimpleRouteEditor } from './typings'
import { localSchema } from './storage'
export { copyText } from './copyText.function'

export const stripeServer = 'https://api.stripe.com/v1/'
const sampleAddress = {
Expand Down Expand Up @@ -157,23 +158,6 @@ export function getProjectLocalStorage(): localSchema {
return storage
}

export function copyText(text: string) {
/* Get the text field */
var copyText = document.createElement('textarea');
copyText.value = text
document.body.appendChild(copyText)

/* Select the text field */
copyText.select();
copyText.setSelectionRange(0, 99999); /* For mobile devices */

/* Copy the text inside the text field */
document.execCommand("copy");

document.body.removeChild(copyText)
// copyText.parentNode.removeChild(copyText)
}

export function changeKey(
scope: Record<any, any>,
value: string,
Expand Down
9 changes: 9 additions & 0 deletions src/components/copyText.function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export function copyText(text: string) {
var copyText = document.createElement('textarea')
copyText.value = text
document.body.appendChild(copyText)
copyText.select()
copyText.setSelectionRange(0, 99999)
document.execCommand("copy")
document.body.removeChild(copyText)
}
171 changes: 16 additions & 155 deletions src/components/dump.component.html
Original file line number Diff line number Diff line change
@@ -1,155 +1,16 @@
<!-- IF 1: undefined ELSE goto simpleTemplate -->
<ng-container *ngIf="[null, undefined].includes(value);else simpleTemplate">
<ng-container *ngTemplateOutlet="dumpSimple;context:{key:key, value:typing}"></ng-container>
</ng-container>

<!-- IF 2: simple value ELSE goto objectTemplate -->
<ng-template #simpleTemplate>
<ng-container *ngIf="['boolean','number','string'].includes(typing); else objectTemplate">
<ng-container *ngTemplateOutlet="dumpSimple;context:{key:key, value:value}"></ng-container>
</ng-container>
</ng-template>

<ng-template #objectTemplate>
<!-- IF 3: object value -->
<ng-container [ngSwitch]="value">
<!--null-->
<ng-container *ngSwitchCase="null">
<ng-container *ngIf="showKids">
<ng-container *ngTemplateOutlet="dumpSimple;context:{key: key, value:'null'}"></ng-container>
</ng-container>
</ng-container>

<ng-container *ngSwitchDefault>
<div *ngIf="isRootDump" style="width: 100%;line-height: 90%;">
<div class="pos-rel">
<div class="pos-abs text-xxxs child-margin-1 flex" style="top:-18px;right:-6px">
<a *ngIf="!format || format==='small'" class="flex-valign-center radius-5 text-white pad-h-xxs hover-bg-balanced"
[ngClass] = "showAll ? 'bg-balanced' : 'bg-dark'"
(click)="showAll = !showAll"
title="hide/show all sub objects"
>👁</a>
<a class="flex-valign-center radius-5 text-white pad-h-xxs hover-bg-balanced"
(click)="formatChange.emit(format='small')"
[class]="!format || format==='small' ? 'bg-positive' : 'bg-dark'"
>small</a>
<a class="flex-valign-center radius-5 text-white pad-h-xxs hover-bg-balanced"
(click)="formatChange.emit(format='json')"
[class]="format==='json' ? 'bg-positive' : 'bg-dark'"
>json</a>
<a class="flex-valign-center radius-5 text-white pad-h-xxs hover-bg-balanced active-bg-energized"
(click)="copyAsJsonText(value)"
[class]="format==='json' ? 'bg-positive' : 'bg-dark'"
>copy</a>
</div>
</div>
<textarea *ngIf="format==='json'" disabled wrap="off" style="width:100%;height:25vh;min-height:400px"
>{{ value | json }}</textArea>
</div>

<ng-container *ngIf="!format || format==='small'">
<!-- array -->
<ng-container *ngIf="value.push && value.pop;else dumpObject">
<div class="border border-radius-5 bg-danger flex-stacked text-dark">
<a class="text-white text-xxs border-white pad-xxs bg-assertive flex-1 flex-apart"
[class.border-bottom] = "show"
>
<strong (click)="show = !show" class="flex-1">{{key}}</strong>
<sup class="opacity-80 text-xs pad-left-xs">
<a (click)="arrayView = arrayView === 'table' ? undefined : 'table'">table</a>
</sup>
<sup class="opacity-80 text-xs pad-left-xs">[{{value.length}}]</sup>
</a>
<div *ngIf="showAll || show || showKids || (show==undefined && showLevels > 0)" class="flex-wrap child-margin-xxs">
<ng-container *ngTemplateOutlet="arrayTable;context:{array:value}"></ng-container>
</div>
</div>
</ng-container>

<!-- object -->
<ng-template #dumpObject>
<div class="flex1">
<div class="border border-radius-5 bg-info flex-stacked text-sm text-dark">
<a *ngIf="key" class="text-white text-xxs border-white pad-xxs bg-positive flex-1 flex-apart"
[class.border-bottom] = "show"
(click)="show = !show"
>
<strong>{{key}}</strong>
<sup class="opacity-80 text-xs pad-left-xs">
<span ng-non-bindable>&#123;</span>{{ (value | keys).length }}<span ng-non-bindable>}</span>
</sup>
</a>
<div *ngIf="!key || showKids || show || (show==undefined && showLevels > 0)" class="flex-wrap">
<ng-container *ngFor="let item of value | keyvalue : unsorted">
<!-- recurse -->
<dump [value]="item.value" [key]="item.key" [showLevels]="showLevels - 1" [showKids]="showAll || showKids"
class="flex-1 overflow flex-wrap child-margin-xxs pad-xxs"
[class.flex1] = "!item.value || typeof(item.value) !== 'object'"
[isRootDump]="false"
></dump>
</ng-container>
</div>
</div>
</div>
</ng-template>
</ng-container>
</ng-container>
</ng-container>
</ng-template>

<ng-template #dumpSimple let-key="key" let-value="value">
<div class="flex1 text-xs text-dark">
<div *ngIf="key" class="strong text-xxs border-white border-bottom" style="line-height: 95%;"
>{{key}}</div>
<ng-container *ngIf="value.search && (value.slice(0,8)==='https://' || value.slice(0,7)==='http://');else simpleValue">
<a (click)="copyText(value)" [href]="value" target="_blank" class="hover-bg-warning active-bg-energized"
title = "tap to copy"
>{{value}}</a>
</ng-container>
<ng-template #simpleValue>
<div (click)="copyText(value)" class="cursor-pointer hover-bg-warning active-bg-energized"
[class.text-balanced]="value === true"
[class.text-assertive]="value === false"
[title] = "value.constructor?.name === 'Number' && value > 1000000000 ? value > 946702800000 ? 'Milliseconds > Unix epoch:\n' + (value | date : 'long') : 'Seconds > Unix epoch:\n' + (value*1000 | date : 'long') : ''"
>{{value}}</div>
</ng-template>
</div>
</ng-template>

<ng-template #arrayTable let-array="array">
<ng-container *ngIf="arrayView === 'table';else arrayDisplay">
<div style="max-height: 800px;overflow-y: scroll;">
<table cellPadding="2" cellSpacing="2" border="0">
<ng-container *ngIf="array.length">
<thead style="position: sticky;top: 0;font-size: 0.8em;">
<tr>
<ng-container *ngFor="let item of array[0] | keyvalue">
<th>{{item.key}}</th>
</ng-container>
</tr>
</thead>
</ng-container>
<tbody>
<ng-container *ngFor="let row of array">
<tr>
<ng-container *ngFor="let item of row | keyvalue">
<td>
<dump [value]="item.value" [showLevels]="showLevels" [showKids]="showAll || showKids" [isRootDump]="false"></dump>
</td>
</ng-container>
</tr>
</ng-container>
</tbody>
</table>
</div>
</ng-container>

<ng-template #arrayDisplay>
<ng-container *ngFor="let item of array">
<!-- recurse -->
<dump [value]="item" [showLevels]="showLevels" [showKids]="showAll || showKids" [isRootDump]="false"></dump>
</ng-container>
</ng-template>
</ng-template>


<tag-element
[id]="dumpTagId"
[attr.props]="({
key: key,
value: value,
show: show,
showKids: showKids,
showLevels: showLevels,
showAll: showAll,
format: format,
isRootDump: isRootDump
}) | json"

events="formatChange"
(formatChange)="formatChange.emit($event.detail.formatChange)"
></tag-element>
47 changes: 5 additions & 42 deletions src/components/dump.component.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,21 @@
import { Component, EventEmitter, Input, Output } from "@angular/core"
import { copyText } from "./app.component.utils"
import { dump } from "taggedjs-dump"
import { loadTagGateway } from "taggedjs-gateway"

@Component({
selector: 'dump',
templateUrl: './dump.component.html',
}) export class DumpComponent {
dumpTagId = loadTagGateway(dump)

@Input() value: any
@Input() showLevels: number = -1 // unfolded shown levels of depth. Default is auto decide
@Input() format: 'json' | 'small' = 'small' // do not pass in, used to detect when first dump
@Output() formatChange: EventEmitter<'json' | 'small'> = new EventEmitter()

@Input() showAll!: boolean // hide entire results
@Input() show!: boolean // hide entire results
@Input() showKids: boolean = false // force children to be shown by true value
@Input() key!: string // dump a key within the provided value
@Input() isRootDump: boolean = true // do not pass in, used to detect when first dump

arrayView?: 'table'
typing?: string
copyText = copyText

ngOnChanges( changes:any ){
this.typing = this.value === null ? 'null' : typeof(this.value)

if (!this.key) {
this.evalShowKids()
}
}

ngOnInit(){
this.evalShowKids()
}

typeof(v) {
return typeof(v)
}

evalShowKids() {
const levelsDefined = (this.showLevels>=0 && this.showLevels)
// detect auto levels (default) and if object lets only show 2 levels deep
const autoShowObjectLevels = this.showLevels === -1 && !this.key && this.isObject()
this.showLevels = levelsDefined || (autoShowObjectLevels ? 2 : 0)

if (this.showLevels > 0) {
this.show = true
}
}

isObject() {
return this.value && this.value instanceof Object
}

unsorted() {} // ensure keyvalue pipe maintains order

copyAsJsonText(value: any) {
copyText( JSON.stringify(value, null, 2) )
}
}
2 changes: 1 addition & 1 deletion src/components/invoices.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ export const invoice_update: ISimpleRouteEditor = {
}

export const invoice_search: ISimpleRouteEditor = {
title: '🔎 search payment intents',
title: '🔎 search invoices',
link: 'https://stripe.com/docs/api/invoices/search',
request: {
method: 'GET',
Expand Down
15 changes: 14 additions & 1 deletion src/components/pay_intents.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,19 @@ export const payintent_search: ISimpleRouteEditor = {
path: 'payment_intents/search',
},
pastes: [],
examples: [{
title: 'succeeded last 14 days',
data: {
limit: 20,
query: "status:'succeeded' AND created>${Math.ceil((Date.now() - 86400000 * 14) / 1000)}"
}
},{
title: 'not succeeded last 14 days',
data: {
limit: 20,
query: "-status:'succeeded' AND created>${Math.ceil((Date.now() - 86400000 * 14) / 1000)}"
}
}],
data: {
limit: 3, query: "metadata['key']:'value'"
}
Expand Down Expand Up @@ -652,4 +665,4 @@ export const payintents: ApiGroup = {
title: '📦 💵 👤 💰 🛳 multiple charges & transfers',
url: 'https://stripe.com/docs/connect/charges-transfers'
}],
}
}
37 changes: 36 additions & 1 deletion src/components/simpleRouteToSmart.function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ export function simpleRouteToSmart(
}

if (routeRef.data && routeRef.examples) {
// look for dynamic
Object.values(routeRef.examples).forEach(example => {
if(!example.data) {
return
}

Object.entries(example.data).forEach(([key, value]) => {
if(typeof(example.data[key]) !== 'string') {
return
}

example.data[key] = interpolate(value)
})
})
routeRef.examples.push({title: 'original data', data: routeRef.data})
}

Expand Down Expand Up @@ -239,4 +253,25 @@ export function simpleMenuToSmart(
end[ key ] = simpleRouteToSmart(value, [])
return end
}, menu as any)
}
}

const defaultEvalContext = {
Date, Math,
}

function interpolate(template, ctx = defaultEvalContext) {
// Use a regular expression to find and replace placeholders
return template.replace(/\${(.*?)}/g, (match, p1) => {
// Use the matched placeholder as a key to get the replacement value
return sandboxEval(p1.trim(), ctx) || match;
});
}

// execute script in private context
function sandboxEval(src, ctx){
ctx = new Proxy(ctx, {
has: () => true
})
let func = (new Function("with(this) { return " + src + "}"));
return func.call(ctx)
}
Loading

0 comments on commit f94d748

Please sign in to comment.