profile
viewpoint

oblador/loki 1685

👁 Visual Regression Testing for Storybook

LA1TV/Hyperdeck-JS-Lib 25

A javascript library for communication with the Blackmagic Hyperdeck.

tjenkinson/CasparCG-Auto-Live-Mixer-Server 7

A server written in java that reads an xml file containing the in, out and breakpoints of audio/video and then receives commands to flow smoothly between the different sections.

tjenkinson/CasparCG-PHP-ServerConnection 5

The CasparCG PHP ServerConnection is a class that is used to manage the connection to communicate with CasparCG Server(s) via the AMCP protocol.

tjenkinson/CasparCG-Java-ServerConnection 2

The CasparCG Java ServerConnection is a library that is used to communicate with CasparCG Server(s) via the AMCP protocol.

alonpeer/web-audio-chrome-glitch 1

https://alonpeer.github.io/web-audio-chrome-glitch/index.html

tjenkinson/babel-private-properties 1

A babel plugin which will convert all private properties (identifiers) to md5 hashes.

tjenkinson/boundary 1

A boundary represents everything below a given point in the call stack and notifies you on entry and exit.

tjenkinson/Adobe-AS3-Animation-Helper 0

A tool to help create complex animations in flash. Uses the tweener at "https://code.google.com/p/tweener/".

pull request commentfeathersjs/feathers

fix(authentication-oauth): Properly handle all oAuth errors

Thanks!

daffl

comment created time in 3 days

startedProseMirror/prosemirror-model

started time in 4 days

startedueberdosis/tiptap

started time in 4 days

startedytdl-org/youtube-dl

started time in 5 days

startedshadcn-ui/ui

started time in 7 days

push eventtjenkinson/ics

Tom Jenkinson

commit sha 0f873a5d99eabd62a5668dcf040f220f9d29ae67

update outputs on readme

view details

push time in 13 days

push eventtjenkinson/ics

Tom Jenkinson

commit sha 43152dee932df89cc996f470e6b420c9cc1df874

remove handling 0 events as special case

view details

push time in 13 days

push eventtjenkinson/ics

Tom Jenkinson

commit sha ab09560bd3a08362de1c7263471e77be57d3b3c9

support passing header params to `createEvents`

view details

push time in 13 days

push eventtjenkinson/ics

Tom Jenkinson

commit sha 71bdc64cb28fb16233a8d33bd7b7f265e7977e5f

use `createEvents` in `createEvent`

view details

push time in 13 days

push eventtjenkinson/ics

Tom Jenkinson

commit sha 06c45d57a86e0b897cadda5581e0237d2dea125f

update type for trigger

view details

push time in 13 days

push eventtjenkinson/ics

Tom Jenkinson

commit sha b1da51acab9772604f0d0647cf77b57608ae7ede

support string date/time in trigger

view details

push time in 13 days

push eventtjenkinson/ics

Tom Jenkinson

commit sha 69a120df89af24aa17d885aecab9adbe45fcb3e3

update types for date/time

view details

push time in 13 days

pull request commentadamgibbons/ics

Allow `organiser` to contain comma, ensure that new lines in values don't break output, and various other tweaks

Just realised I still need to update the d.ts file

tjenkinson

comment created time in 13 days

startedadamgibbons/ics

started time in 13 days

Pull request review commentadamgibbons/ics

Allow `organiser` to contain comma, ensure that new lines in values don't break output, and various other tweaks

 export default function formatEvent(attributes = {}) {     classification,     created,     lastModified,-    calName,     htmlContent   } = attributes    let icsFormat = ''-  icsFormat += 'BEGIN:VCALENDAR\r\n'-  icsFormat += 'VERSION:2.0\r\n'-  icsFormat += 'CALSCALE:GREGORIAN\r\n'-  icsFormat += foldLine(`PRODID:${productId}`) + '\r\n'-  icsFormat += foldLine(`METHOD:${method}`) + '\r\n'-  icsFormat += calName ? (foldLine(`X-WR-CALNAME:${calName}`) + '\r\n') : ''-  icsFormat += `X-PUBLISHED-TTL:PT1H\r\n`   icsFormat += 'BEGIN:VEVENT\r\n'-  icsFormat += `UID:${uid}\r\n`-  icsFormat +=  foldLine(`SUMMARY:${title ? setSummary(title) : title}`) + '\r\n'

I think this was a bug and the intent was to not include the line if there was no title?

tjenkinson

comment created time in 13 days

Pull request review commentadamgibbons/ics

Allow `organiser` to contain comma, ensure that new lines in values don't break output, and various other tweaks

 export function convertTimestampToArray(timestamp, inputType = 'local') { }  export function createEvent (attributes, cb) {-  if (!attributes) { Error('Attributes argument is required') }+  const run = () => {+    if (!attributes) {+      return { error: new Error('Attributes argument is required'), value: null }+    } -  assignUniqueId(attributes)+    const { error, value } = buildHeaderAndEventAndValidate(attributes)+    if (error) return { error, value }++    const event = formatHeader(value) + formatEvent(value) + formatFooter()+    return { error: null, value: event }+  }++  let returnValue;+  try {+    returnValue = run();+  } catch (e) {+    returnValue = { error: e, value: null }+  }    if (!cb) {-    // No callback, so return error or value in an object-    const { error, value } = validateAndBuildEvent(attributes)+    return returnValue+  } -    if (error) return { error, value }+  return cb(returnValue.error, returnValue.value)+} -    let event = ''+export function createEvents (events, cb) {+  const run = () => {+    if (!events) {+      return { error: new Error('one argument is required'), value: null }+    } -    try {-      event = formatEvent(value)-    } catch(error) {-      return { error, value: null }+    if (events.length === 1) {+      return createEvent(events[0])     } -    return { error: null, value: event }-  }+    if (events.length === 0) {+      const { error, value } = buildHeaderAndValidate({});+      if (error) return {error, value: null} -  // Return a node-style callback-  const { error, value } = validateAndBuildEvent(attributes)+      return {+        error: null,+        value: formatHeader(value) + formatFooter()+      }+    } -  if (error) return cb(error) -  return cb(null, formatEvent(value))-}+    const { error: headerError, value: headerValue } = buildHeaderAndEventAndValidate(events[0]);+    if (headerError) {+      return {error: headerError, value: null}+    } -export function createEvents (events, cb) {-  if (!events) {-    return { error: Error('one argument is required'), value: null }-  }+    let value = ''+    value += formatHeader(headerValue) -  if (events.length === 0) {-    const {error, value: dummy} = createEvent({-      start: [2000, 10, 5, 5, 0],-      duration: { hours: 1 }-    })-    if (error) return {error, value: null}--    return {-      error: null,-      value: (-        dummy.slice(0, dummy.indexOf('BEGIN:VEVENT')) +-        dummy.slice(dummy.indexOf('END:VEVENT') + 10 + 2)-      )

previously this wasn't calling cb if provided

tjenkinson

comment created time in 13 days

Pull request review commentadamgibbons/ics

Allow `organiser` to contain comma, ensure that new lines in values don't break output, and various other tweaks

 export function convertTimestampToArray(timestamp, inputType = 'local') { }  export function createEvent (attributes, cb) {-  if (!attributes) { Error('Attributes argument is required') }

this was never actually thrown before

tjenkinson

comment created time in 13 days

Pull request review commentadamgibbons/ics

Allow `organiser` to contain comma, ensure that new lines in values don't break output, and various other tweaks

 const alarmSchema = yup.object().shape({   'iana-prop': yup.mixed() }).noUnknown() -const schema = yup.object().shape({-  summary: yup.string(),-  timestamp: yup.mixed(),-  title: yup.string(),+const headerShape = {   productId: yup.string(),   method: yup.string(),-  uid: yup.string().required(),+  calName: yup.string()+}++const headerSchema = yup.object().shape(headerShape).noUnknown()++const eventShape = {+  summary: yup.string(),+  timestamp: dateTimeSchema({ required: false }),+  title: yup.string(),+  uid: yup.string(),   sequence: yup.number().integer().max(2_147_483_647),-  start: dateTimeSchema.required(),+  start: dateTimeSchema({ required: true }),   duration: durationSchema,-  startType: yup.string().matches(/utc|local/),-  startInputType: yup.string().matches(/utc|local/),-  startOutputType: yup.string().matches(/utc|local/),-  end: dateTimeSchema,-  endInputType: yup.string().matches(/utc|local/),-  endOutputType: yup.string().matches(/utc|local/),+  startType: yup.string().matches(/^(utc|local)$/),+  startInputType: yup.string().matches(/^(utc|local)$/),+  startOutputType: yup.string().matches(/^(utc|local)$/),+  end: dateTimeSchema({ required: false }),+  endInputType: yup.string().matches(/^(utc|local)$/),+  endOutputType: yup.string().matches(/^(utc|local)$/),   description: yup.string(),   url: yup.string().matches(urlRegex),   geo: yup.object().shape({lat: yup.number(), lon: yup.number()}),   location: yup.string(),-  status: yup.string().matches(/TENTATIVE|CANCELLED|CONFIRMED/i),+  status: yup.string().matches(/^(TENTATIVE|CANCELLED|CONFIRMED)$/i),   categories: yup.array().of(yup.string()),   organizer: organizerSchema,   attendees: yup.array().of(contactSchema),   alarms: yup.array().of(alarmSchema),   recurrenceRule: yup.string(),-  busyStatus: yup.string().matches(/TENTATIVE|FREE|BUSY|OOF/i),-  transp: yup.string().matches(/TRANSPARENT|OPAQUE/i),+  busyStatus: yup.string().matches(/^(TENTATIVE|FREE|BUSY|OOF)$/i),+  transp: yup.string().matches(/^(TRANSPARENT|OPAQUE)$/i),   classification: yup.string(),-  created: dateTimeSchema,-  lastModified: dateTimeSchema,-  calName: yup.string(),+  created: dateTimeSchema({ required: false }),+  lastModified: dateTimeSchema({ required: false }),+  exclusionDates: yup.array().of(dateTimeSchema({ required: true })),

this was previously missing

tjenkinson

comment created time in 13 days

PullRequestReviewEvent
PullRequestReviewEvent

PR opened adamgibbons/ics

Escape organiser and contact

Thanks for this great library!

We had a bug where we were providing an organiser where the name included a ,, and the fix was to wrap the name in quotes. Essentially take the quoted-string option for param-value in the spec

So the I decided to make the same change to the other param-value's so that they don't have the same issue.

And then I added some logic to encode new lines to\n in a lot more places because otherwise it's possible for user input containing new lines to break things

And as I was going through I spotted a few other things so here's a list of all the tweaks/fixes

  • exclusionDates was missing in the schema so I don't think it could be used before? Now it can be and I changed it to be an array of date/time entries
  • date time entries can now be a single number which is the unix time, which is easy to get from date.getTime(), or a string which is then just passed through
  • the default values are now built with a fn at runtime as this means the default date will be the invoke time and not the time when the library was loaded, and also means the uuid is unique every time and assignUniqueId was no longer needed
  • some of the regex patterns in the schema check weren't bounded. I.e. oopsCANCELLED would be allowed
  • I split up the event into header/event/footer (the second commit). This makes it a bit cleaner when there are no events as don't need to do any string searching anymore. I didn't change the api so it still takes the calendar name etc from the first event object, but in the future it might be worth updating the public api to support passing the header fields separately to the event ones, so that then if you are creating a calendar feed where the are no events it's still possible to set the header fields and not get the defaults
  • added encodeParamValue which is used to encode param-value's. The spec doesn't appear to say that "'s are allowed in the string, but escaping them with \ does seem to work when I tested in the apple calendar app
+425 -327

0 comment

24 changed files

pr created time in 13 days

create barnchtjenkinson/ics

branch : escape-organiser-and-contact

created branch time in 13 days

fork tjenkinson/ics

iCalendar (ics) file generator for node.js

fork in 14 days

startedKidkArolis/kinfolk

started time in 14 days

PR opened KidkArolis/kinfolk

Also `pop()` getters on an error

I think it's quite unlikely someone would hit this, but anyway,

If you run

/* eslint-disable react/jsx-no-bind */

import React from 'react'
import { createRoot } from 'react-dom/client'
import {
  Provider,
  createStore,
  atom,
  selector,
  useSelector,
  useSetter,
} from '../../src/kinfolk.js'
import './styles.css'

const store = createStore()
const counter = atom(0, { label: 'counter' })
const double = selector(
  () => {
    throw new Error('oops')
    return counter() * 2
  },
  { label: 'double' },
)

window.store = store
window.counter = counter

function App() {
  const val = useSelector(counter)
  const dub = useSelector(() => {
    try {
      return double()
    } catch {
      return -1
    }
  })
  const set = useSetter(counter)
  return (
    <div>
      {val} / {dub} <button onClick={() => set(val + 1)}>Increment</button>
    </div>
  )
}

createRoot(document.querySelector('#root')).render(
  <Provider store={store}>
    <App />
  </Provider>,
)

and watch the size of __getters it will keep increasing.

Also this then means calling window.counter() doesn't throw the error it should as it thinks it's inside a selector

Maybe in a bigger app if you have error boundaries and shared atoms this could actually cause a bigger issue 🤷

+5 -3

0 comment

1 changed file

pr created time in 14 days

create barnchtjenkinson/kinfolk

branch : always-cleanup-getters

created branch time in 14 days

fork tjenkinson/kinfolk

Atoms and selectors for React

fork in 14 days

issue commentfeathersjs/feathers

oauth auth service still called even if `grant` returns an error

Ah yes that looks likely. You can trigger it if you set state: true, and then tweak the state in the url when logging in so that it no longer matches in the callback :)

tjenkinson

comment created time in 16 days

pull request commentnegrel/http_ece

configure github actions workflow and publish to npm

Amazing thanks

tjenkinson

comment created time in 17 days

startednegrel/http_ece

started time in 17 days

more