🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more →

svelte-forms-lib

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

svelte-forms-lib - npm Package Compare versions

Comparing version

to
0.2.2

@@ -1,563 +0,1311 @@

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.index = factory());
}(this, function () { 'use strict';
'use strict';
function noop() { }
function run(fn) {
return fn();
Object.defineProperty(exports, '__esModule', { value: true });
function noop() { }
function assign(tar, src) {
// @ts-ignore
for (const k in src)
tar[k] = src[k];
return tar;
}
function run(fn) {
return fn();
}
function blank_object() {
return Object.create(null);
}
function run_all(fns) {
fns.forEach(run);
}
function is_function(thing) {
return typeof thing === 'function';
}
function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}
function subscribe(store, callback) {
const unsub = store.subscribe(callback);
return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
}
function component_subscribe(component, store, callback) {
component.$$.on_destroy.push(subscribe(store, callback));
}
function create_slot(definition, ctx, fn) {
if (definition) {
const slot_ctx = get_slot_context(definition, ctx, fn);
return definition[0](slot_ctx);
}
function run_all(fns) {
fns.forEach(run);
}
function get_slot_context(definition, ctx, fn) {
return definition[1]
? assign({}, assign(ctx.$$scope.ctx, definition[1](fn ? fn(ctx) : {})))
: ctx.$$scope.ctx;
}
function get_slot_changes(definition, ctx, changed, fn) {
return definition[1]
? assign({}, assign(ctx.$$scope.changed || {}, definition[1](fn ? fn(changed) : {})))
: ctx.$$scope.changed || {};
}
function exclude_internal_props(props) {
const result = {};
for (const k in props)
if (k[0] !== '$')
result[k] = props[k];
return result;
}
function append(target, node) {
target.appendChild(node);
}
function insert(target, node, anchor) {
target.insertBefore(node, anchor || null);
}
function detach(node) {
node.parentNode.removeChild(node);
}
function element(name) {
return document.createElement(name);
}
function text(data) {
return document.createTextNode(data);
}
function empty() {
return text('');
}
function listen(node, event, handler, options) {
node.addEventListener(event, handler, options);
return () => node.removeEventListener(event, handler, options);
}
function attr(node, attribute, value) {
if (value == null)
node.removeAttribute(attribute);
else
node.setAttribute(attribute, value);
}
function set_attributes(node, attributes) {
for (const key in attributes) {
if (key === 'style') {
node.style.cssText = attributes[key];
}
else if (key in node) {
node[key] = attributes[key];
}
else {
attr(node, key, attributes[key]);
}
}
function is_function(thing) {
return typeof thing === 'function';
}
function children(element) {
return Array.from(element.childNodes);
}
function set_data(text, data) {
data = '' + data;
if (text.data !== data)
text.data = data;
}
function set_input_value(input, value) {
if (value != null || input.value) {
input.value = value;
}
function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}
let current_component;
function set_current_component(component) {
current_component = component;
}
function get_current_component() {
if (!current_component)
throw new Error(`Function called outside component initialization`);
return current_component;
}
function setContext(key, context) {
get_current_component().$$.context.set(key, context);
}
function getContext(key) {
return get_current_component().$$.context.get(key);
}
const dirty_components = [];
const binding_callbacks = [];
const render_callbacks = [];
const flush_callbacks = [];
const resolved_promise = Promise.resolve();
let update_scheduled = false;
function schedule_update() {
if (!update_scheduled) {
update_scheduled = true;
resolved_promise.then(flush);
}
}
function add_render_callback(fn) {
render_callbacks.push(fn);
}
function flush() {
const seen_callbacks = new Set();
do {
// first, call beforeUpdate functions
// and update components
while (dirty_components.length) {
const component = dirty_components.shift();
set_current_component(component);
update(component.$$);
}
while (binding_callbacks.length)
binding_callbacks.pop()();
// then, once components are updated, call
// afterUpdate functions. This may cause
// subsequent updates...
for (let i = 0; i < render_callbacks.length; i += 1) {
const callback = render_callbacks[i];
if (!seen_callbacks.has(callback)) {
callback();
// ...so guard against infinite loops
seen_callbacks.add(callback);
}
}
render_callbacks.length = 0;
} while (dirty_components.length);
while (flush_callbacks.length) {
flush_callbacks.pop()();
}
update_scheduled = false;
}
function update($$) {
if ($$.fragment) {
$$.update($$.dirty);
run_all($$.before_update);
$$.fragment.p($$.dirty, $$.ctx);
$$.dirty = null;
$$.after_update.forEach(add_render_callback);
}
}
const outroing = new Set();
let outros;
function transition_in(block, local) {
if (block && block.i) {
outroing.delete(block);
block.i(local);
}
}
function transition_out(block, local, detach, callback) {
if (block && block.o) {
if (outroing.has(block))
return;
outroing.add(block);
outros.c.push(() => {
outroing.delete(block);
if (callback) {
if (detach)
block.d(1);
callback();
}
});
block.o(local);
}
}
const subscriber_queue = [];
/**
* Creates a `Readable` store that allows reading by subscription.
* @param value initial value
* @param {StartStopNotifier}start start and stop notifications for subscriptions
*/
function readable(value, start) {
return {
subscribe: writable(value, start).subscribe,
};
}
/**
* Create a `Writable` store that allows both updating and reading by subscription.
* @param {*=}value initial value
* @param {StartStopNotifier=}start start and stop notifications for subscriptions
*/
function writable(value, start = noop) {
let stop;
const subscribers = [];
function set(new_value) {
if (safe_not_equal(value, new_value)) {
value = new_value;
if (stop) { // store is ready
const run_queue = !subscriber_queue.length;
for (let i = 0; i < subscribers.length; i += 1) {
const s = subscribers[i];
s[1]();
subscriber_queue.push(s, value);
}
if (run_queue) {
for (let i = 0; i < subscriber_queue.length; i += 2) {
subscriber_queue[i][0](subscriber_queue[i + 1]);
}
subscriber_queue.length = 0;
}
function get_spread_update(levels, updates) {
const update = {};
const to_null_out = {};
const accounted_for = { $$scope: 1 };
let i = levels.length;
while (i--) {
const o = levels[i];
const n = updates[i];
if (n) {
for (const key in o) {
if (!(key in n))
to_null_out[key] = 1;
}
for (const key in n) {
if (!accounted_for[key]) {
update[key] = n[key];
accounted_for[key] = 1;
}
}
levels[i] = n;
}
function update(fn) {
set(fn(value));
else {
for (const key in o) {
accounted_for[key] = 1;
}
}
function subscribe(run, invalidate = noop) {
const subscriber = [run, invalidate];
subscribers.push(subscriber);
if (subscribers.length === 1) {
stop = start(set) || noop;
}
for (const key in to_null_out) {
if (!(key in update))
update[key] = undefined;
}
return update;
}
function mount_component(component, target, anchor) {
const { fragment, on_mount, on_destroy, after_update } = component.$$;
fragment.m(target, anchor);
// onMount happens before the initial afterUpdate
add_render_callback(() => {
const new_on_destroy = on_mount.map(run).filter(is_function);
if (on_destroy) {
on_destroy.push(...new_on_destroy);
}
else {
// Edge case - component was destroyed immediately,
// most likely as a result of a binding initialising
run_all(new_on_destroy);
}
component.$$.on_mount = [];
});
after_update.forEach(add_render_callback);
}
function destroy_component(component, detaching) {
if (component.$$.fragment) {
run_all(component.$$.on_destroy);
component.$$.fragment.d(detaching);
// TODO null out other refs, including component.$$ (but need to
// preserve final state?)
component.$$.on_destroy = component.$$.fragment = null;
component.$$.ctx = {};
}
}
function make_dirty(component, key) {
if (!component.$$.dirty) {
dirty_components.push(component);
schedule_update();
component.$$.dirty = blank_object();
}
component.$$.dirty[key] = true;
}
function init(component, options, instance, create_fragment, not_equal, prop_names) {
const parent_component = current_component;
set_current_component(component);
const props = options.props || {};
const $$ = component.$$ = {
fragment: null,
ctx: null,
// state
props: prop_names,
update: noop,
not_equal,
bound: blank_object(),
// lifecycle
on_mount: [],
on_destroy: [],
before_update: [],
after_update: [],
context: new Map(parent_component ? parent_component.$$.context : []),
// everything else
callbacks: blank_object(),
dirty: null
};
let ready = false;
$$.ctx = instance
? instance(component, props, (key, value) => {
if ($$.ctx && not_equal($$.ctx[key], $$.ctx[key] = value)) {
if ($$.bound[key])
$$.bound[key](value);
if (ready)
make_dirty(component, key);
}
run(value);
return () => {
const index = subscribers.indexOf(subscriber);
if (index !== -1) {
subscribers.splice(index, 1);
}
if (subscribers.length === 0) {
stop();
stop = null;
}
};
})
: props;
$$.update();
ready = true;
run_all($$.before_update);
$$.fragment = create_fragment($$.ctx);
if (options.target) {
if (options.hydrate) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$$.fragment.l(children(options.target));
}
return { set, update, subscribe };
else {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$$.fragment.c();
}
if (options.intro)
transition_in(component.$$.fragment);
mount_component(component, options.target, options.anchor);
flush();
}
/**
* Derived value store by synchronizing one or more readable stores and
* applying an aggregation function over its input values.
* @param {Stores} stores input stores
* @param {function(Stores=, function(*)=):*}fn function callback that aggregates the values
* @param {*=}initial_value when used asynchronously
*/
function derived(stores, fn, initial_value) {
const single = !Array.isArray(stores);
const stores_array = single
? [stores]
: stores;
const auto = fn.length < 2;
return readable(initial_value, (set) => {
let inited = false;
const values = [];
let pending = 0;
let cleanup = noop;
const sync = () => {
if (pending) {
return;
set_current_component(parent_component);
}
class SvelteComponent {
$destroy() {
destroy_component(this, 1);
this.$destroy = noop;
}
$on(type, callback) {
const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));
callbacks.push(callback);
return () => {
const index = callbacks.indexOf(callback);
if (index !== -1)
callbacks.splice(index, 1);
};
}
$set() {
// overridden by instance, if it has props
}
}
const subscriber_queue = [];
/**
* Creates a `Readable` store that allows reading by subscription.
* @param value initial value
* @param {StartStopNotifier}start start and stop notifications for subscriptions
*/
function readable(value, start) {
return {
subscribe: writable(value, start).subscribe,
};
}
/**
* Create a `Writable` store that allows both updating and reading by subscription.
* @param {*=}value initial value
* @param {StartStopNotifier=}start start and stop notifications for subscriptions
*/
function writable(value, start = noop) {
let stop;
const subscribers = [];
function set(new_value) {
if (safe_not_equal(value, new_value)) {
value = new_value;
if (stop) { // store is ready
const run_queue = !subscriber_queue.length;
for (let i = 0; i < subscribers.length; i += 1) {
const s = subscribers[i];
s[1]();
subscriber_queue.push(s, value);
}
cleanup();
const result = fn(single ? values[0] : values, set);
if (auto) {
set(result);
if (run_queue) {
for (let i = 0; i < subscriber_queue.length; i += 2) {
subscriber_queue[i][0](subscriber_queue[i + 1]);
}
subscriber_queue.length = 0;
}
else {
cleanup = is_function(result) ? result : noop;
}
};
const unsubscribers = stores_array.map((store, i) => store.subscribe((value) => {
values[i] = value;
pending &= ~(1 << i);
if (inited) {
sync();
}
}, () => {
pending |= (1 << i);
}));
inited = true;
sync();
return function stop() {
run_all(unsubscribers);
cleanup();
};
});
}
}
}
function update(fn) {
set(fn(value));
}
function subscribe(run, invalidate = noop) {
const subscriber = [run, invalidate];
subscribers.push(subscriber);
if (subscribers.length === 1) {
stop = start(set) || noop;
}
run(value);
return () => {
const index = subscribers.indexOf(subscriber);
if (index !== -1) {
subscribers.splice(index, 1);
}
if (subscribers.length === 0) {
stop();
stop = null;
}
};
}
return { set, update, subscribe };
}
/**
* Derived value store by synchronizing one or more readable stores and
* applying an aggregation function over its input values.
* @param {Stores} stores input stores
* @param {function(Stores=, function(*)=):*}fn function callback that aggregates the values
* @param {*=}initial_value when used asynchronously
*/
function derived(stores, fn, initial_value) {
const single = !Array.isArray(stores);
const stores_array = single
? [stores]
: stores;
const auto = fn.length < 2;
return readable(initial_value, (set) => {
let inited = false;
const values = [];
let pending = 0;
let cleanup = noop;
const sync = () => {
if (pending) {
return;
}
cleanup();
const result = fn(single ? values[0] : values, set);
if (auto) {
set(result);
}
else {
cleanup = is_function(result) ? result : noop;
}
};
const unsubscribers = stores_array.map((store, i) => store.subscribe((value) => {
values[i] = value;
pending &= ~(1 << i);
if (inited) {
sync();
}
}, () => {
pending |= (1 << i);
}));
inited = true;
sync();
return function stop() {
run_all(unsubscribers);
cleanup();
};
});
}
/**
* Based on Kendo UI Core expression code <https://github.com/telerik/kendo-ui-core#license-information>
*/
/**
* Based on Kendo UI Core expression code <https://github.com/telerik/kendo-ui-core#license-information>
*/
function Cache(maxSize) {
this._maxSize = maxSize;
this.clear();
function Cache(maxSize) {
this._maxSize = maxSize;
this.clear();
}
Cache.prototype.clear = function() {
this._size = 0;
this._values = {};
};
Cache.prototype.get = function(key) {
return this._values[key]
};
Cache.prototype.set = function(key, value) {
this._size >= this._maxSize && this.clear();
if (!this._values.hasOwnProperty(key)) {
this._size++;
}
return this._values[key] = value
};
var SPLIT_REGEX = /[^.^\]^[]+|(?=\[\]|\.\.)/g,
DIGIT_REGEX = /^\d+$/,
LEAD_DIGIT_REGEX = /^\d/,
SPEC_CHAR_REGEX = /[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g,
CLEAN_QUOTES_REGEX = /^\s*(['"]?)(.*?)(\1)\s*$/,
MAX_CACHE_SIZE = 512;
var contentSecurityPolicy = false,
pathCache = new Cache(MAX_CACHE_SIZE),
setCache = new Cache(MAX_CACHE_SIZE),
getCache = new Cache(MAX_CACHE_SIZE);
try {
new Function('');
} catch (error) {
contentSecurityPolicy = true;
}
var propertyExpr = {
Cache: Cache,
expr: expr,
split: split,
normalizePath: normalizePath,
setter: contentSecurityPolicy
? function(path) {
var parts = normalizePath(path);
return function(data, value) {
return setterFallback(parts, data, value)
}
}
Cache.prototype.clear = function() {
this._size = 0;
this._values = {};
};
Cache.prototype.get = function(key) {
return this._values[key]
};
Cache.prototype.set = function(key, value) {
this._size >= this._maxSize && this.clear();
if (!this._values.hasOwnProperty(key)) {
this._size++;
: function(path) {
return setCache.get(path) || setCache.set(
path,
new Function(
'data, value',
expr(path, 'data') + ' = value'
)
)
},
getter: contentSecurityPolicy
? function(path, safe) {
var parts = normalizePath(path);
return function(data) {
return getterFallback(parts, safe, data)
}
return this._values[key] = value
};
}
: function(path, safe) {
var key = path + '_' + safe;
return getCache.get(key) || getCache.set(
key,
new Function('data', 'return ' + expr(path, safe, 'data'))
)
},
var SPLIT_REGEX = /[^.^\]^[]+|(?=\[\]|\.\.)/g,
DIGIT_REGEX = /^\d+$/,
LEAD_DIGIT_REGEX = /^\d/,
SPEC_CHAR_REGEX = /[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g,
CLEAN_QUOTES_REGEX = /^\s*(['"]?)(.*?)(\1)\s*$/,
MAX_CACHE_SIZE = 512;
join: function(segments) {
return segments.reduce(function(path, part) {
return (
path +
(isQuoted(part) || DIGIT_REGEX.test(part)
? '[' + part + ']'
: (path ? '.' : '') + part)
)
}, '')
},
var contentSecurityPolicy = false,
pathCache = new Cache(MAX_CACHE_SIZE),
setCache = new Cache(MAX_CACHE_SIZE),
getCache = new Cache(MAX_CACHE_SIZE);
forEach: function(path, cb, thisArg) {
forEach(split(path), cb, thisArg);
}
};
try {
new Function('');
} catch (error) {
contentSecurityPolicy = true;
function setterFallback(parts, data, value) {
var index = 0,
len = parts.length;
while (index < len - 1) {
data = data[parts[index++]];
}
data[parts[index]] = value;
}
function getterFallback(parts, safe, data) {
var index = 0,
len = parts.length;
while (index < len) {
if (data != null || !safe) {
data = data[parts[index++]];
} else {
return
}
}
return data
}
var propertyExpr = {
Cache: Cache,
function normalizePath(path) {
return pathCache.get(path) || pathCache.set(
path,
split(path).map(function(part) {
return part.replace(CLEAN_QUOTES_REGEX, '$2')
})
)
}
expr: expr,
function split(path) {
return path.match(SPLIT_REGEX)
}
split: split,
function expr(expression, safe, param) {
expression = expression || '';
normalizePath: normalizePath,
if (typeof safe === 'string') {
param = safe;
safe = false;
}
setter: contentSecurityPolicy
? function(path) {
var parts = normalizePath(path);
return function(data, value) {
return setterFallback(parts, data, value)
}
}
: function(path) {
return setCache.get(path) || setCache.set(
path,
new Function(
'data, value',
expr(path, 'data') + ' = value'
)
)
},
param = param || 'data';
getter: contentSecurityPolicy
? function(path, safe) {
var parts = normalizePath(path);
return function(data) {
return getterFallback(parts, safe, data)
}
}
: function(path, safe) {
var key = path + '_' + safe;
return getCache.get(key) || getCache.set(
key,
new Function('data', 'return ' + expr(path, safe, 'data'))
)
},
if (expression && expression.charAt(0) !== '[') expression = '.' + expression;
join: function(segments) {
return segments.reduce(function(path, part) {
return (
path +
(isQuoted(part) || DIGIT_REGEX.test(part)
? '[' + part + ']'
: (path ? '.' : '') + part)
)
}, '')
},
return safe ? makeSafe(expression, param) : param + expression
}
forEach: function(path, cb, thisArg) {
forEach(split(path), cb, thisArg);
}
};
function forEach(parts, iter, thisArg) {
var len = parts.length,
part,
idx,
isArray,
isBracket;
function setterFallback(parts, data, value) {
var index = 0,
len = parts.length;
while (index < len - 1) {
data = data[parts[index++]];
}
data[parts[index]] = value;
}
for (idx = 0; idx < len; idx++) {
part = parts[idx];
function getterFallback(parts, safe, data) {
var index = 0,
len = parts.length;
while (index < len) {
if (data != null || !safe) {
data = data[parts[index++]];
} else {
return
}
if (part) {
if (shouldBeQuoted(part)) {
part = '"' + part + '"';
}
return data
}
function normalizePath(path) {
return pathCache.get(path) || pathCache.set(
path,
split(path).map(function(part) {
return part.replace(CLEAN_QUOTES_REGEX, '$2')
})
)
}
isBracket = isQuoted(part);
isArray = !isBracket && /^\d+$/.test(part);
function split(path) {
return path.match(SPLIT_REGEX)
iter.call(thisArg, part, isBracket, isArray, idx, parts);
}
}
}
function expr(expression, safe, param) {
expression = expression || '';
function isQuoted(str) {
return (
typeof str === 'string' && str && ["'", '"'].indexOf(str.charAt(0)) !== -1
)
}
if (typeof safe === 'string') {
param = safe;
safe = false;
}
function makeSafe(path, param) {
var result = param,
parts = split(path),
isLast;
param = param || 'data';
forEach(parts, function(part, isBracket, isArray, idx, parts) {
isLast = idx === parts.length - 1;
if (expression && expression.charAt(0) !== '[') expression = '.' + expression;
part = isBracket || isArray ? '[' + part + ']' : '.' + part;
return safe ? makeSafe(expression, param) : param + expression
}
result += part + (!isLast ? ' || {})' : ')');
});
function forEach(parts, iter, thisArg) {
var len = parts.length,
part,
idx,
isArray,
isBracket;
return new Array(parts.length + 1).join('(') + result
}
for (idx = 0; idx < len; idx++) {
part = parts[idx];
function hasLeadingNumber(part) {
return part.match(LEAD_DIGIT_REGEX) && !part.match(DIGIT_REGEX)
}
if (part) {
if (shouldBeQuoted(part)) {
part = '"' + part + '"';
}
function hasSpecialChars(part) {
return SPEC_CHAR_REGEX.test(part)
}
isBracket = isQuoted(part);
isArray = !isBracket && /^\d+$/.test(part);
function shouldBeQuoted(part) {
return !isQuoted(part) && (hasLeadingNumber(part) || hasSpecialChars(part))
}
var propertyExpr_8 = propertyExpr.forEach;
iter.call(thisArg, part, isBracket, isArray, idx, parts);
}
function subscribeOnce(observable) {
return new Promise(resolve => {
observable.subscribe(resolve)(); // immediately invoke to unsubscribe
});
}
function update$1(obj, path, val) {
obj.update(o => {
set(o, path, val);
return o;
});
}
function cloneDeep(obj) {
return JSON.parse(JSON.stringify(obj));
}
function isEmpty(obj) {
return Object.keys(obj).length <= 0;
}
function getValues(obj) {
let result = [];
for (const key in obj) {
result = result.concat(typeof obj[key] === "object" ? getValues(obj[key]) : obj[key]);
}
return result;
}
function assignDeep(obj, val) {
if (Array.isArray(obj)) {
return obj.map(o => assignDeep(o, val));
}
const copy = {};
for (const key in obj) {
copy[key] = typeof obj[key] === "object" ? assignDeep(obj[key], val) : val;
}
return copy;
}
function has(object, key) {
return object != null && Object.prototype.hasOwnProperty.call(object, key);
}
function set(obj, path, value) {
if (Object(obj) !== obj) return obj;
if (!Array.isArray(path)) {
path = path.toString().match(/[^.[\]]+/g) || [];
}
const res = path
.slice(0, -1)
.reduce(
(acc, key, index) =>
Object(acc[key]) === acc[key]
? acc[key]
: (acc[key] = Math.abs(path[index + 1]) >> 0 === +path[index + 1] ? [] : {}),
obj
);
res[path[path.length - 1]] = value;
return obj;
}
// Implementation of yup.reach
// TODO rewrite to simpler version and remove dependency on forEach
function reach(obj, path, value, context) {
return getIn(obj, path, value, context).schema;
}
function trim(part) {
return part.substr(0, part.length - 1).substr(1);
}
function getIn(schema, path, value, context) {
let parent, lastPart;
context = context || value;
if (!path)
return {
parent,
parentPath: path,
schema
};
propertyExpr_8(path, (_part, isBracket, isArray) => {
let part = isBracket ? trim(_part) : _part;
if (isArray || has(schema, "_subType")) {
let index = isArray ? parseInt(part, 10) : 0;
schema = schema.resolve({ context, parent, value })._subType;
if (value) {
value = value[index];
}
}
function isQuoted(str) {
return (
typeof str === 'string' && str && ["'", '"'].indexOf(str.charAt(0)) !== -1
)
if (!isArray) {
schema = schema.resolve({ context, parent, value });
schema = schema.fields[part];
parent = value;
value = value && value[part];
lastPart = part;
}
});
function makeSafe(path, param) {
var result = param,
parts = split(path),
isLast;
return { schema, parent, parentPath: lastPart };
}
forEach(parts, function(part, isBracket, isArray, idx, parts) {
isLast = idx === parts.length - 1;
const util = {
subscribeOnce,
update: update$1,
cloneDeep,
isEmpty,
assignDeep,
reach,
getValues
};
part = isBracket || isArray ? '[' + part + ']' : '.' + part;
const NO_ERROR = "";
const IS_TOUCHED = true;
result += part + (!isLast ? ' || {})' : ')');
});
const createForm = config => {
const initialValues = config.initialValues || {};
return new Array(parts.length + 1).join('(') + result
}
if (Object.keys(initialValues).length < 1) {
const provided = JSON.stringify(initialValues);
console.warn(
`createForm requires initialValues to be a non empty object or array, provided ${provided}`
);
return;
}
function hasLeadingNumber(part) {
return part.match(LEAD_DIGIT_REGEX) && !part.match(DIGIT_REGEX)
}
const validationSchema = config.validationSchema;
const validateFn = config.validate;
const onSubmit = config.onSubmit;
function hasSpecialChars(part) {
return SPEC_CHAR_REGEX.test(part)
}
const initial = {
values: () => util.cloneDeep(initialValues),
errors: () => util.assignDeep(initialValues, NO_ERROR),
touched: () => util.assignDeep(initialValues, !IS_TOUCHED)
};
function shouldBeQuoted(part) {
return !isQuoted(part) && (hasLeadingNumber(part) || hasSpecialChars(part))
}
var propertyExpr_8 = propertyExpr.forEach;
const form = writable(initial.values());
const errors = writable(initial.errors());
const touched = writable(initial.touched());
function subscribeOnce(observable) {
return new Promise(resolve => {
observable.subscribe(resolve)(); // immediately invoke to unsubscribe
const isSubmitting = writable(false);
const isValidating = writable(false);
const isValid = derived([errors, touched], ([$errors, $touched]) => {
const allTouched = util.getValues($touched).every(field => field === IS_TOUCHED);
const noErrors = util.getValues($errors).every(field => field === NO_ERROR);
return allTouched && noErrors;
});
function handleChange(event) {
const { name: field, value } = event.target;
updateTouched(field, true);
if (validationSchema) {
isValidating.set(true);
return util
.reach(validationSchema, field)
.validate(value)
.then(() => util.update(errors, field, ""))
.catch(err => util.update(errors, field, err.message))
.finally(() => {
updateField(field, value);
isValidating.set(false);
});
}
function update(obj, path, val) {
obj.update(o => {
set(o, path, val);
return o;
});
updateField(field, value);
}
function handleSubmit(ev) {
if (ev && ev.preventDefault) {
ev.preventDefault();
}
function cloneDeep(obj) {
return JSON.parse(JSON.stringify(obj));
}
function isEmpty(obj) {
return Object.keys(obj).length <= 0;
}
function getValues(obj) {
let result = [];
for (const key in obj) {
result = result.concat(typeof obj[key] === "object" ? getValues(obj[key]) : obj[key]);
}
return result;
}
function assignDeep(obj, val) {
if (Array.isArray(obj)) {
return obj.map(o => assignDeep(o, val));
}
const copy = {};
for (const key in obj) {
copy[key] = typeof obj[key] === "object" ? assignDeep(obj[key], val) : val;
}
return copy;
}
function has(object, key) {
return object != null && Object.prototype.hasOwnProperty.call(object, key);
}
function set(obj, path, value) {
if (Object(obj) !== obj)
return obj;
if (!Array.isArray(path)) {
path = path.toString().match(/[^.[\]]+/g) || [];
}
const res = path
.slice(0, -1)
.reduce((acc, key, index) => Object(acc[key]) === acc[key]
? acc[key]
: (acc[key] = Math.abs(path[index + 1]) >> 0 === +path[index + 1] ? [] : {}), obj);
res[path[path.length - 1]] = value;
return obj;
}
// Implementation of yup.reach
// TODO rewrite to simpler version and remove dependency on forEach
function reach(obj, path, value, context) {
return getIn(obj, path, value, context).schema;
}
function trim(part) {
return part.substr(0, part.length - 1).substr(1);
}
function getIn(schema, path, value, context) {
let parent, lastPart;
context = context || value;
if (!path)
return {
parent,
parentPath: path,
schema
};
propertyExpr_8(path, (_part, isBracket, isArray) => {
let part = isBracket ? trim(_part) : _part;
if (isArray || has(schema, "_subType")) {
let index = isArray ? parseInt(part, 10) : 0;
schema = schema.resolve({ context, parent, value })._subType;
if (value) {
value = value[index];
}
isSubmitting.set(true);
return util.subscribeOnce(form).then(values => {
if (typeof validateFn === "function") {
isValidating.set(true);
return Promise.resolve()
.then(() => validateFn(values))
.then(err => {
if (util.isEmpty(err)) {
clearErrorsAndSubmit(values);
} else {
errors.set(err);
isValidating.set(false);
}
if (!isArray) {
schema = schema.resolve({ context, parent, value });
schema = schema.fields[part];
parent = value;
value = value && value[part];
lastPart = part;
}
});
return { schema, parent, parentPath: lastPart };
}
const util = {
subscribeOnce,
update,
cloneDeep,
isEmpty,
assignDeep,
reach,
getValues
};
});
}
const NO_ERROR = "";
const IS_TOUCHED = true;
const createForm = (config) => {
const initialValues = config.initialValues || {};
if (Object.keys(initialValues).length < 1) {
const provided = JSON.stringify(initialValues);
console.warn(`createForm requires initialValues to be a non empty object or array, provided ${provided}`);
return;
}
const validationSchema = config.validationSchema;
const validateFn = config.validate;
const onSubmit = config.onSubmit;
const initial = {
values: () => util.cloneDeep(initialValues),
errors: () => util.assignDeep(initialValues, NO_ERROR),
touched: () => util.assignDeep(initialValues, !IS_TOUCHED)
};
const form = writable(initial.values());
const errors = writable(initial.errors());
const touched = writable(initial.touched());
const isSubmitting = writable(false);
const isValidating = writable(false);
const isValid = derived([errors, touched], ([$errors, $touched]) => {
const allTouched = util.getValues($touched).every(field => field === IS_TOUCHED);
const noErrors = util.getValues($errors).every(field => field === NO_ERROR);
return allTouched && noErrors;
});
function handleChange(event) {
const { name: field, value } = event.target;
updateTouched(field, true);
if (validationSchema) {
isValidating.set(true);
return util
.reach(validationSchema, field)
.validate(value)
.then(() => util.update(errors, field, ""))
.catch(err => util.update(errors, field, err.message))
.finally(() => {
updateField(field, value);
isValidating.set(false);
});
if (validationSchema) {
isValidating.set(true);
return validationSchema
.validate(values, { abortEarly: false })
.then(() => clearErrorsAndSubmit(values))
.catch(yupErrs => {
if (yupErrs && yupErrs.inner) {
yupErrs.inner.forEach(error => util.update(errors, error.path, error.message));
}
updateField(field, value);
}
function handleSubmit(ev) {
if (ev && ev.preventDefault) {
ev.preventDefault();
}
isSubmitting.set(true);
return util.subscribeOnce(form).then(values => {
if (typeof validateFn === "function") {
isValidating.set(true);
return Promise.resolve()
.then(() => validateFn(values))
.then(err => {
if (util.isEmpty(err)) {
clearErrorsAndSubmit(values);
}
else {
errors.set(err);
isValidating.set(false);
}
});
}
if (validationSchema) {
isValidating.set(true);
return validationSchema
.validate(values, { abortEarly: false })
.then(() => clearErrorsAndSubmit(values))
.catch(yupErrs => {
if (yupErrs && yupErrs.inner) {
yupErrs.inner.forEach(error => util.update(errors, error.path, error.message));
}
isSubmitting.set(false);
})
.finally(() => isValidating.set(false));
}
clearErrorsAndSubmit(values);
});
}
function handleReset() {
form.set(initial.values());
errors.set(initial.errors());
touched.set(initial.touched());
}
function clearErrorsAndSubmit(values) {
return Promise.resolve()
.then(() => errors.set(util.assignDeep(values, "")))
.then(() => onSubmit(values, form, errors))
.finally(() => isSubmitting.set(false));
}
/**
* Handler to imperatively update the value of a form field
*/
function updateField(field, value) {
util.update(form, field, value);
}
/**
* Handler to imperatively update the touched value of a form field
*/
function updateTouched(field, value) {
util.update(touched, field, value);
}
return {
form,
errors,
touched,
isValid,
isSubmitting,
isValidating,
handleChange,
handleSubmit,
handleReset,
updateField,
updateTouched,
state: derived([form, errors, touched, isValid, isValidating, isSubmitting], ([$form, $errors, $touched, $isValid, $isValidating, $isSubmitting]) => ({
form: $form,
errors: $errors,
touched: $touched,
isValid: $isValid,
isSubmitting: $isSubmitting,
isValidating: $isValidating
}))
};
};
isSubmitting.set(false);
})
.finally(() => isValidating.set(false));
}
return createForm;
clearErrorsAndSubmit(values);
});
}
}));
//# sourceMappingURL=index.js.map
function handleReset() {
form.set(initial.values());
errors.set(initial.errors());
touched.set(initial.touched());
}
function clearErrorsAndSubmit(values) {
return Promise.resolve()
.then(() => errors.set(util.assignDeep(values, "")))
.then(() => onSubmit(values, form, errors))
.finally(() => isSubmitting.set(false));
}
/**
* Handler to imperatively update the value of a form field
*/
function updateField(field, value) {
util.update(form, field, value);
}
/**
* Handler to imperatively update the touched value of a form field
*/
function updateTouched(field, value) {
util.update(touched, field, value);
}
return {
form,
errors,
touched,
isValid,
isSubmitting,
isValidating,
handleChange,
handleSubmit,
handleReset,
updateField,
updateTouched,
state: derived(
[form, errors, touched, isValid, isValidating, isSubmitting],
([$form, $errors, $touched, $isValid, $isValidating, $isSubmitting]) => ({
form: $form,
errors: $errors,
touched: $touched,
isValid: $isValid,
isSubmitting: $isSubmitting,
isValidating: $isValidating
})
)
};
};
const key = {};
/* lib/components/Form.svelte generated by Svelte v3.10.0 */
const get_default_slot_changes = ({ form, errors, touched, state, handleChange, handleSubmit, updateField, updateTouched }) => ({});
const get_default_slot_context = ({ form, errors, touched, state, handleChange, handleSubmit, updateField, updateTouched }) => ({
form: form,
errors: errors,
touched: touched,
state: state,
handleChange: handleChange,
handleSubmit: handleSubmit,
updateField: updateField,
updateTouched: updateTouched
});
function create_fragment(ctx) {
var form_1, current, dispose;
const default_slot_template = ctx.$$slots.default;
const default_slot = create_slot(default_slot_template, ctx, get_default_slot_context);
var form_1_levels = [
ctx.$$props
];
var form_1_data = {};
for (var i = 0; i < form_1_levels.length; i += 1) {
form_1_data = assign(form_1_data, form_1_levels[i]);
}
return {
c() {
form_1 = element("form");
if (default_slot) default_slot.c();
set_attributes(form_1, form_1_data);
dispose = listen(form_1, "submit", ctx.handleSubmit);
},
l(nodes) {
if (default_slot) default_slot.l(form_1_nodes);
},
m(target, anchor) {
insert(target, form_1, anchor);
if (default_slot) {
default_slot.m(form_1, null);
}
current = true;
},
p(changed, ctx) {
if (default_slot && default_slot.p && changed.$$scope) {
default_slot.p(
get_slot_changes(default_slot_template, ctx, changed, get_default_slot_changes),
get_slot_context(default_slot_template, ctx, get_default_slot_context)
);
}
set_attributes(form_1, get_spread_update(form_1_levels, [
(changed.$$props) && ctx.$$props
]));
},
i(local) {
if (current) return;
transition_in(default_slot, local);
current = true;
},
o(local) {
transition_out(default_slot, local);
current = false;
},
d(detaching) {
if (detaching) {
detach(form_1);
}
if (default_slot) default_slot.d(detaching);
dispose();
}
};
}
function instance($$self, $$props, $$invalidate) {
let { initialValues, validate, validationSchema, onSubmit } = $$props;
const {
form,
errors,
touched,
state,
handleChange,
handleSubmit,
updateField,
updateTouched
} = createForm({
initialValues,
validationSchema,
validate,
onSubmit
});
setContext(key, {
form,
errors,
touched,
state,
handleChange,
handleSubmit,
updateField,
updateTouched
});
let { $$slots = {}, $$scope } = $$props;
$$self.$set = $$new_props => {
$$invalidate('$$props', $$props = assign(assign({}, $$props), $$new_props));
if ('initialValues' in $$new_props) $$invalidate('initialValues', initialValues = $$new_props.initialValues);
if ('validate' in $$new_props) $$invalidate('validate', validate = $$new_props.validate);
if ('validationSchema' in $$new_props) $$invalidate('validationSchema', validationSchema = $$new_props.validationSchema);
if ('onSubmit' in $$new_props) $$invalidate('onSubmit', onSubmit = $$new_props.onSubmit);
if ('$$scope' in $$new_props) $$invalidate('$$scope', $$scope = $$new_props.$$scope);
};
return {
initialValues,
validate,
validationSchema,
onSubmit,
form,
errors,
touched,
state,
handleChange,
handleSubmit,
updateField,
updateTouched,
$$props,
$$props: $$props = exclude_internal_props($$props),
$$slots,
$$scope
};
}
class Form extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, ["initialValues", "validate", "validationSchema", "onSubmit"]);
}
}
/* lib/components/Field.svelte generated by Svelte v3.10.0 */
function create_fragment$1(ctx) {
var input, dispose;
var input_levels = [
{ type: "text" },
{ name: ctx.name },
ctx.$$props
];
var input_data = {};
for (var i = 0; i < input_levels.length; i += 1) {
input_data = assign(input_data, input_levels[i]);
}
return {
c() {
input = element("input");
set_attributes(input, input_data);
dispose = [
listen(input, "input", ctx.input_input_handler),
listen(input, "change", ctx.handleChange),
listen(input, "blur", ctx.handleChange)
];
},
m(target, anchor) {
insert(target, input, anchor);
set_input_value(input, ctx.$form[ctx.name]);
},
p(changed, ctx) {
if ((changed.$form || changed.name) && (input.value !== ctx.$form[ctx.name])) set_input_value(input, ctx.$form[ctx.name]);
set_attributes(input, get_spread_update(input_levels, [
{ type: "text" },
(changed.name) && { name: ctx.name },
(changed.$$props) && ctx.$$props
]));
},
i: noop,
o: noop,
d(detaching) {
if (detaching) {
detach(input);
}
run_all(dispose);
}
};
}
function instance$1($$self, $$props, $$invalidate) {
let $form;
let { name } = $$props;
const { form, handleChange } = getContext(key); component_subscribe($$self, form, $$value => { $form = $$value; $$invalidate('$form', $form); });
function input_input_handler() {
form.update($$value => ($$value[name] = this.value, $$value));
$$invalidate('name', name);
}
$$self.$set = $$new_props => {
$$invalidate('$$props', $$props = assign(assign({}, $$props), $$new_props));
if ('name' in $$new_props) $$invalidate('name', name = $$new_props.name);
};
return {
name,
form,
handleChange,
$form,
$$props,
input_input_handler,
$$props: $$props = exclude_internal_props($$props)
};
}
class Field extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance$1, create_fragment$1, safe_not_equal, ["name"]);
}
}
/* lib/components/ErrorMessage.svelte generated by Svelte v3.10.0 */
// (10:0) {#if $errors[name]}
function create_if_block(ctx) {
var small, t_value = ctx.$errors[ctx.name] + "", t;
var small_levels = [
ctx.$$props
];
var small_data = {};
for (var i = 0; i < small_levels.length; i += 1) {
small_data = assign(small_data, small_levels[i]);
}
return {
c() {
small = element("small");
t = text(t_value);
set_attributes(small, small_data);
},
m(target, anchor) {
insert(target, small, anchor);
append(small, t);
},
p(changed, ctx) {
if ((changed.$errors || changed.name) && t_value !== (t_value = ctx.$errors[ctx.name] + "")) {
set_data(t, t_value);
}
set_attributes(small, get_spread_update(small_levels, [
(changed.$$props) && ctx.$$props
]));
},
d(detaching) {
if (detaching) {
detach(small);
}
}
};
}
function create_fragment$2(ctx) {
var if_block_anchor;
var if_block = (ctx.$errors[ctx.name]) && create_if_block(ctx);
return {
c() {
if (if_block) if_block.c();
if_block_anchor = empty();
},
m(target, anchor) {
if (if_block) if_block.m(target, anchor);
insert(target, if_block_anchor, anchor);
},
p(changed, ctx) {
if (ctx.$errors[ctx.name]) {
if (if_block) {
if_block.p(changed, ctx);
} else {
if_block = create_if_block(ctx);
if_block.c();
if_block.m(if_block_anchor.parentNode, if_block_anchor);
}
} else if (if_block) {
if_block.d(1);
if_block = null;
}
},
i: noop,
o: noop,
d(detaching) {
if (if_block) if_block.d(detaching);
if (detaching) {
detach(if_block_anchor);
}
}
};
}
function instance$2($$self, $$props, $$invalidate) {
let $errors;
let { name } = $$props;
const { errors } = getContext(key); component_subscribe($$self, errors, $$value => { $errors = $$value; $$invalidate('$errors', $errors); });
$$self.$set = $$new_props => {
$$invalidate('$$props', $$props = assign(assign({}, $$props), $$new_props));
if ('name' in $$new_props) $$invalidate('name', name = $$new_props.name);
};
return {
name,
errors,
$errors,
$$props,
$$props: $$props = exclude_internal_props($$props)
};
}
class ErrorMessage extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance$2, create_fragment$2, safe_not_equal, ["name"]);
}
}
exports.ErrorMessage = ErrorMessage;
exports.Field = Field;
exports.Form = Form;
exports.createForm = createForm;
{
"name": "svelte-forms-lib",
"version": "0.2.1",
"version": "0.2.2",
"description": "Svelte forms lib - A lightweight library for managing forms in Svelte v3",

@@ -9,7 +9,7 @@ "scripts": {

"build": "NODE_ENV=production rollup -c rollup.config.js",
"build:examples": "rollup -c rollup.examples.config.js -w",
"build:examples": "rollup -c rollup.config.examples.js -w",
"prepare": "npm run build",
"test": "jest",
"test:watch": "jest --watchAll",
"format": "prettier --write lib/**/*.{ts,css}",
"format": "prettier --write lib/**/*.{js,css}",
"serve:examples": "sirv dist-examples --single --dev"

@@ -36,2 +36,3 @@ },

"main": "./dist/index.js",
"module": "./dist/index.mjs",
"license": "MIT",

@@ -65,2 +66,3 @@ "dependencies": {

"svelte": "3.10.0",
"svelte-ts-preprocess": "1.1.3",
"ts-jest": "24.0.2",

@@ -67,0 +69,0 @@ "tslib": "1.10.0",

@@ -231,2 +231,39 @@

### Using helper components to reduce boilerplate i.e. `Form`, `Field` and `ErrorMessage`
To reduce the boilerplate it is also possible to use additional helper components i.e. `Form`, `Field` and `ErrorMessage`. Usage can be done as follows:
```svelte
<script>
import { Form, Field, ErrorMessage } from "svelte-forms-lib";
import yup from "yup";
</script>
<Form
initialValues={{
name: "",
email: ""
}}
validationSchema={yup.object().shape({
name: yup.string().required(),
email: yup.string().email().required()
})}
onSubmit={values => {
alert(JSON.stringify(values, null, 2))
}}
>
<label>name</label>
<Field name="name" />
<ErrorMessage name="name" />
<label>email</label>
<Field name="email" />
<ErrorMessage name="email" />
<button type="submit">submit</button>
</Form>
```
The components are using context API to get the form state and handlers so that you don't have to set that up. All props passed to the helper components will be passed down to the element it's mapped to. The `Form` is mapped to `<form>`, `Field` to `<input>` and `ErrorMessage` to `<small>`.
### Handling form arrays

@@ -233,0 +270,0 @@