@yongdall/authenticator 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/assets/web.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{Store as e,createStoreField as t,renderStore as n}from"@yongdall/web";import r from"@yongdall/web/plugin";const i=[/[a-z]/,/[A-Z]/,/[0-9]/,/[~!@#$%^&*()_+{}|<>?,./:";'\\\[\]-]/];function*a(e){e.length<8&&(yield`密码不足 8 位`),i.filter(t=>t.test(e)).length<3&&(yield`密码至少包含小写字母、大写字母、数字、符号中的 3 种`),e.toLowerCase().includes(`admin`)&&(yield`密码不能包含admin`),[...e].find((e,t,n)=>n[t-1]===e&&n[t+1]===e)&&(yield`密码不能包含三位以上的相同的字母或数字`),[...e].find((e,t,n)=>{let r=n[t-1],i=n[t+1];if(!r||!i)return!1;let a=r.charCodeAt(0),o=e.charCodeAt(0),s=i.charCodeAt(0),c=a-o,l=o-s;if(c===l&&(l===1||l===-1))return!0})&&(yield`密码不能包含三位以上的连续的字母或数字`)}const o={resetPassword:{type:`bool`},username:{type:`string`,label:`用户名`,validators:{blur(e){let t=e.value;if(!t||typeof t!=`string`)return`请填写用户名`}}},password:{type:`password`,label:`密码`,validators:{blur(e){let t=e.value;if(!t||typeof t!=`string`)return`请填写密码`}}},newPassword:{type:{password1:{type:`password`,label:`新密码`,validator:e=>{if(!e.root.child(`resetPassword`)?.value)return;let t=e.value;return!t||typeof t!=`string`?`请填写新密码`:[...a(t)]}},password2:{type:`password`,label:`重复密码`,validator:e=>{if(!e.root.child(`resetPassword`)?.value)return;let t=e.value;if(!t)return`请填写重复密码`;if(t!==e.parent?.child(`password1`)?.value)return`重复密码与新密码不一致`}}},label:`重置密码`,hidden:e=>!e.root.child(`resetPassword`)?.value}},s={fields:[{field:`username`},{field:`password`},{field:`newPassword`,fields:[{field:`password1`},{field:`password2`}]}]};function c(i,a){let c=document.createElement(`form`),l=c.appendChild(document.createElement(`h2`));l.textContent=`用户登录`,c.appendChild(l);let u=e.create(o);if(u.reset(),i.aborted)return null;let d=n(u,(e,n)=>t(e,{},n),c,s,{editable:!0});i.addEventListener(`abort`,d,{once:!0});let f=c.appendChild(document.createElement(`button`));return f.type=`submit`,f.textContent=`登录`,c.addEventListener(`submit`,async e=>{if(e.preventDefault(),!f.disabled)try{f.disabled=!0;let{username:e,password:t,resetPassword:n,newPassword:{password1:i}}=u.value;if((await u.validate())?.length)return;let o=await r.request.clone().put().body({login:e,password:t,newPassword:n&&i||``}).result();if(!o||typeof o==`object`){a();return}if(o===408){let e=u.child(`resetPassword`);e&&(e.value=!0);return}if(o===404){alert(`用户名错误`);let e=u.child(`resetPassword`);e&&(e.value=!1);return}if(o===403){alert(`用户名或密码错误`);let e=u.child(`resetPassword`);e&&(e.value=!1);return}}catch(e){e instanceof Response&&(e.status===404?alert(`用户名错误`):e.status===403?alert(`密码错误`):e.status)}finally{f.disabled=!1}}),c}const l=document.createElement(`div`);l.classList.add(`yongdall-authenticator`);const u={styleFiles:[`style.css`],classNames:[],elements:l,async login(e){let{promise:t,resolve:n}=Promise.withResolvers(),r=new Promise(t=>{if(e.aborted){t();return}e.addEventListener(`abort`,()=>t(),{once:!0})}),i=c(e,n);i&&(l.appendChild(i),await Promise.race([t,r]).finally(()=>{i.remove()}))}};export{u as authenticator};
1
+ import{Store as e,renderStoreForm as t}from"@yongdall/web";import n from"@yongdall/web/plugin";const r=[/[a-z]/,/[A-Z]/,/[0-9]/,/[~!@#$%^&*()_+{}|<>?,./:";'\\\[\]-]/];function*i(e){e.length<8&&(yield`密码不足 8 位`),r.filter(t=>t.test(e)).length<3&&(yield`密码至少包含小写字母、大写字母、数字、符号中的 3 种`),e.toLowerCase().includes(`admin`)&&(yield`密码不能包含admin`),[...e].find((e,t,n)=>n[t-1]===e&&n[t+1]===e)&&(yield`密码不能包含三位以上的相同的字母或数字`),[...e].find((e,t,n)=>{let r=n[t-1],i=n[t+1];if(!r||!i)return!1;let a=r.charCodeAt(0),o=e.charCodeAt(0),s=i.charCodeAt(0),c=a-o,l=o-s;if(c===l&&(l===1||l===-1))return!0})&&(yield`密码不能包含三位以上的连续的字母或数字`)}const a={resetPassword:{type:`bool`},username:{type:`string`,label:`用户名`,validators:{blur(e){let t=e.value;if(!t||typeof t!=`string`)return`请填写用户名`}}},password:{type:`string`,label:`密码`,component:`password`,validators:{blur(e){let t=e.value;if(!t||typeof t!=`string`)return`请填写密码`}}},newPassword:{type:{password1:{type:`string`,label:`新密码`,component:`password`,validator:e=>{if(!e.root.child(`resetPassword`)?.value)return;let t=e.value;return!t||typeof t!=`string`?`请填写新密码`:[...i(t)]}},password2:{type:`string`,label:`重复密码`,component:`password`,validator:e=>{if(!e.root.child(`resetPassword`)?.value)return;let t=e.value;if(!t)return`请填写重复密码`;if(t!==e.parent?.child(`password1`)?.value)return`重复密码与新密码不一致`}}},label:`重置密码`,hidden:e=>!e.root.child(`resetPassword`)?.value}},o={fields:[{field:`username`},{field:`password`},{field:`newPassword`,fields:[{field:`password1`},{field:`password2`}]}]};function s(r,i){let s=document.createElement(`form`),c=s.appendChild(document.createElement(`h2`));c.textContent=`用户登录`,s.appendChild(c);let l=e.create(a);if(l.reset(),r.aborted)return null;t(l,s,{editable:!0,signal:r,layout:o});let u=s.appendChild(document.createElement(`button`));return u.type=`submit`,u.textContent=`登录`,s.addEventListener(`submit`,async e=>{if(e.preventDefault(),!u.disabled)try{u.disabled=!0;let{username:e,password:t,resetPassword:r,newPassword:{password1:a}}=l.value;if((await l.validate())?.length)return;let o=await n.request.clone().put().body({login:e,password:t,newPassword:r&&a||``}).result();if(!o||typeof o==`object`){i();return}if(o===408){let e=l.child(`resetPassword`);e&&(e.value=!0);return}if(o===404){alert(`用户名错误`);let e=l.child(`resetPassword`);e&&(e.value=!1);return}if(o===403){alert(`用户名或密码错误`);let e=l.child(`resetPassword`);e&&(e.value=!1);return}}catch(e){e instanceof Response&&(e.status===404?alert(`用户名错误`):e.status===403?alert(`密码错误`):e.status)}finally{u.disabled=!1}}),s}const c=document.createElement(`div`);c.classList.add(`yongdall-authenticator`);const l={styleFiles:[`style.css`],classNames:[],elements:c,async login(e){let{promise:t,resolve:n}=Promise.withResolvers(),r=new Promise(t=>{if(e.aborted){t();return}e.addEventListener(`abort`,()=>t(),{once:!0})}),i=s(e,n);i&&(c.appendChild(i),await Promise.race([t,r]).finally(()=>{i.remove()}))}};export{l as authenticator};
2
2
  //# sourceMappingURL=web.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"web.mjs","names":[],"sources":["../../../packages/authenticator/verifyNewPassword.mjs","../../../packages/authenticator/createLogin.mjs","../../../packages/authenticator/web.mjs"],"sourcesContent":["const signTypeRegex = [\n\t/[a-z]/,\n\t/[A-Z]/,\n\t/[0-9]/,\n\t/[~!@#$%^&*()_+{}|<>?,./:\";'\\\\\\[\\]-]/,\n]\n/**\n * \n * @param {string} password \n */\nexport function* verifyNewPassword(password) {\n\tif (password.length < 8) { yield '密码不足 8 位'; }\n\t\n\tif (signTypeRegex.filter(r => r.test(password)).length < 3) {\n\t\tyield `密码至少包含小写字母、大写字母、数字、符号中的 3 种`;\n\t}\n\tif (password.toLowerCase().includes('admin')) {\n\t\tyield `密码不能包含admin`;\n\t}\n\tif ([...password].find((a,index, list) => list[index - 1] === a && list[index + 1] === a)) {\n\t\tyield `密码不能包含三位以上的相同的字母或数字`;\n\t}\n\tif ([...password].find((a,index, list) => {\n\t\tconst p = list[index - 1];\n\t\tconst n = list[index + 1];\n\t\tif (!p || !n) { return false; }\n\t\tconst x = p.charCodeAt(0);\n\t\tconst y = a.charCodeAt(0);\n\t\tconst z = n.charCodeAt(0);\n\t\tconst u = x - y;\n\t\tconst v = y - z;\n\t\tif (u === v && (v === 1 || v === -1)) { return true}\n\t})) {\n\t\tyield `密码不能包含三位以上的连续的字母或数字`;\n\t}\n}\n","/** @import { Schema, StoreLayout } from '@yongdall/web' */\n\nimport { createStoreField, renderStore, Store } from '@yongdall/web';\nimport Plugin from '@yongdall/web/plugin';\nimport { verifyNewPassword } from './verifyNewPassword.mjs';\n\n/** @type {Schema} */\nconst schema = {\n\tresetPassword: { type: 'bool' },\n\tusername: {\n\t\ttype: 'string', label: '用户名', validators: {\n\t\t\tblur(store) {\n\t\t\t\tconst value = store.value;\n\t\t\t\tif (!value || typeof value !== 'string') { return '请填写用户名'; }\n\t\t\t},\n\t\t}\n\t},\n\n\tpassword: {\n\t\ttype: 'password', label: '密码',\n\t\tvalidators: {\n\t\t\tblur(store) {\n\t\t\t\tconst value = store.value;\n\t\t\t\tif (!value || typeof value !== 'string') { return '请填写密码'; }\n\t\t\t},\n\t\t}\n\t},\n\tnewPassword: {\n\t\ttype: {\n\t\t\tpassword1: {\n\t\t\t\ttype: 'password', label: '新密码',\n\t\t\t\tvalidator: store => {\n\t\t\t\t\tif (!store.root.child('resetPassword')?.value) { return; }\n\t\t\t\t\tconst value = store.value;\n\t\t\t\t\tif (!value || typeof value !== 'string') { return '请填写新密码'; }\n\n\t\t\t\t\treturn [...verifyNewPassword(value)];\n\t\t\t\t},\n\t\t\t},\n\t\t\tpassword2: {\n\t\t\t\ttype: 'password', label: '重复密码',\n\t\t\t\tvalidator: store => {\n\t\t\t\t\tif (!store.root.child('resetPassword')?.value) { return; }\n\t\t\t\t\tconst value = store.value;\n\t\t\t\t\tif (!value) { return '请填写重复密码'; }\n\t\t\t\t\tif (value !== store.parent?.child('password1')?.value) {\n\t\t\t\t\t\treturn '重复密码与新密码不一致';\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t}, label: '重置密码', hidden: s => !s.root.child('resetPassword')?.value\n\t}\n};\n\n/** @type {StoreLayout} */\nconst StoreLayout = {\n\tfields: [\n\t\t{ field: 'username' },\n\t\t{ field: 'password' },\n\t\t{\n\t\t\tfield: 'newPassword',\n\t\t\tfields: [\n\t\t\t\t{ field: 'password1' },\n\t\t\t\t{ field: 'password2' },\n\t\t\t],\n\t\t},\n\t],\n};\n/**\n * \n * @param {AbortSignal} signal \n * @param {() => void} resolve \n */\nexport default function createLogin(signal, resolve) {\n\t// 创建表单\n\tconst form = document.createElement('form');\n\tconst title = form.appendChild(document.createElement('h2'));\n\ttitle.textContent = '用户登录';\n\tform.appendChild(title);\n\tconst store = Store.create(schema);\n\tstore.reset();\n\tif (signal.aborted) {\n\t\treturn null;\n\t}\n\n\n\tconst destroy = renderStore(\n\t\tstore,\n\t\t(store, options) => createStoreField(store, {}, options),\n\t\tform,\n\t\tStoreLayout,\n\t\t{ editable: true },\n\t);\n\tsignal.addEventListener('abort', destroy, { once: true });\n\n\t// 创建提交按钮\n\tconst submitButton = form.appendChild(document.createElement('button'));\n\tsubmitButton.type = 'submit';\n\tsubmitButton.textContent = '登录';\n\n\t// 添加事件监听器\n\tform.addEventListener('submit', async event => {\n\t\tevent.preventDefault();\n\t\tif (submitButton.disabled) { return; }\n\t\ttry {\n\t\t\tsubmitButton.disabled = true;\n\t\t\tconst { username, password, resetPassword, newPassword: { password1: newPassword } } = store.value;\n\t\t\tconst r = await store.validate();\n\t\t\tif (r?.length) { return; }\n\t\t\tconst result = await Plugin.request.clone().put().body({\n\t\t\t\tlogin: username, password, newPassword: resetPassword && newPassword || '',\n\t\t\t}).result();\n\t\t\tif (!result || typeof result === 'object') {\n\t\t\t\tresolve();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (result === 408) {\n\t\t\t\tconst resetPassword = store.child('resetPassword');\n\t\t\t\tif (resetPassword) { resetPassword.value = true; }\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (result === 404) {\n\t\t\t\talert('用户名错误');\n\t\t\t\tconst resetPassword = store.child('resetPassword');\n\t\t\t\tif (resetPassword) { resetPassword.value = false; }\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (result === 403) {\n\t\t\t\talert('用户名或密码错误');\n\t\t\t\tconst resetPassword = store.child('resetPassword');\n\t\t\t\tif (resetPassword) { resetPassword.value = false; }\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t} catch (e) {\n\t\t\tif (e instanceof Response) {\n\t\t\t\tif (e.status === 404) {\n\t\t\t\t\talert('用户名错误');\n\t\t\t\t} else if (e.status === 403) {\n\t\t\t\t\talert('密码错误');\n\t\t\t\t} else if (e.status === 408) {\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tsubmitButton.disabled = false;\n\t\t}\n\t});\n\n\treturn form;\n}\n","/** @import {Authenticator} from '@yongdall/web' */\nimport createLogin from './createLogin.mjs';\n\nconst root = document.createElement('div');\nroot.classList.add('yongdall-authenticator');\n\n/**@type {Partial<Authenticator>} */\nexport const authenticator = {\n\tstyleFiles: ['style.css'],\n\tclassNames: [],\n\telements: root,\n\tasync login(signal) {\n\t\t/** @type {PromiseWithResolvers<void>} */\n\t\tconst { promise, resolve } = Promise.withResolvers();\n\t\t/*** @type {Promise<void>} */\n\t\tconst signalPromise = new Promise(r => {\n\t\t\tif (signal.aborted) { r(); return; }\n\t\t\tsignal.addEventListener('abort', () => r(), { once: true });\n\t\t});\n\t\tconst form = createLogin(signal, resolve);\n\t\tif (!form) { return; }\n\t\troot.appendChild(form);\n\t\tawait Promise.race([promise, signalPromise])\n\t\t\t.finally(() => { form.remove(); });\n\t},\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"web.mjs","names":[],"sources":["../../../packages/authenticator/verifyNewPassword.mjs","../../../packages/authenticator/createLogin.mjs","../../../packages/authenticator/web.mjs"],"sourcesContent":["const signTypeRegex = [\n\t/[a-z]/,\n\t/[A-Z]/,\n\t/[0-9]/,\n\t/[~!@#$%^&*()_+{}|<>?,./:\";'\\\\\\[\\]-]/,\n]\n/**\n * \n * @param {string} password \n */\nexport function* verifyNewPassword(password) {\n\tif (password.length < 8) { yield '密码不足 8 位'; }\n\t\n\tif (signTypeRegex.filter(r => r.test(password)).length < 3) {\n\t\tyield `密码至少包含小写字母、大写字母、数字、符号中的 3 种`;\n\t}\n\tif (password.toLowerCase().includes('admin')) {\n\t\tyield `密码不能包含admin`;\n\t}\n\tif ([...password].find((a,index, list) => list[index - 1] === a && list[index + 1] === a)) {\n\t\tyield `密码不能包含三位以上的相同的字母或数字`;\n\t}\n\tif ([...password].find((a,index, list) => {\n\t\tconst p = list[index - 1];\n\t\tconst n = list[index + 1];\n\t\tif (!p || !n) { return false; }\n\t\tconst x = p.charCodeAt(0);\n\t\tconst y = a.charCodeAt(0);\n\t\tconst z = n.charCodeAt(0);\n\t\tconst u = x - y;\n\t\tconst v = y - z;\n\t\tif (u === v && (v === 1 || v === -1)) { return true}\n\t})) {\n\t\tyield `密码不能包含三位以上的连续的字母或数字`;\n\t}\n}\n","/** @import { Schema, StoreLayout } from '@yongdall/web' */\n\nimport { renderStoreForm, Store } from '@yongdall/web';\nimport Plugin from '@yongdall/web/plugin';\nimport { verifyNewPassword } from './verifyNewPassword.mjs';\n\n/** @type {Schema} */\nconst schema = {\n\tresetPassword: { type: 'bool' },\n\tusername: {\n\t\ttype: 'string', label: '用户名', validators: {\n\t\t\tblur(store) {\n\t\t\t\tconst value = store.value;\n\t\t\t\tif (!value || typeof value !== 'string') { return '请填写用户名'; }\n\t\t\t},\n\t\t}\n\t},\n\n\tpassword: {\n\t\ttype: 'string', label: '密码', component: 'password',\n\t\tvalidators: {\n\t\t\tblur(store) {\n\t\t\t\tconst value = store.value;\n\t\t\t\tif (!value || typeof value !== 'string') { return '请填写密码'; }\n\t\t\t},\n\t\t}\n\t},\n\tnewPassword: {\n\t\ttype: {\n\t\t\tpassword1: {\n\t\t\t\ttype: 'string', label: '新密码', component: 'password',\n\t\t\t\tvalidator: store => {\n\t\t\t\t\tif (!store.root.child('resetPassword')?.value) { return; }\n\t\t\t\t\tconst value = store.value;\n\t\t\t\t\tif (!value || typeof value !== 'string') { return '请填写新密码'; }\n\n\t\t\t\t\treturn [...verifyNewPassword(value)];\n\t\t\t\t},\n\t\t\t},\n\t\t\tpassword2: {\n\t\t\t\ttype: 'string', label: '重复密码', component: 'password',\n\t\t\t\tvalidator: store => {\n\t\t\t\t\tif (!store.root.child('resetPassword')?.value) { return; }\n\t\t\t\t\tconst value = store.value;\n\t\t\t\t\tif (!value) { return '请填写重复密码'; }\n\t\t\t\t\tif (value !== store.parent?.child('password1')?.value) {\n\t\t\t\t\t\treturn '重复密码与新密码不一致';\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t}, label: '重置密码', hidden: s => !s.root.child('resetPassword')?.value\n\t}\n};\n\n/** @type {StoreLayout<any>} */\nconst layout = {\n\tfields: [\n\t\t{ field: 'username' },\n\t\t{ field: 'password' },\n\t\t{\n\t\t\tfield: 'newPassword',\n\t\t\tfields: [\n\t\t\t\t{ field: 'password1' },\n\t\t\t\t{ field: 'password2' },\n\t\t\t],\n\t\t},\n\t],\n};\n/**\n * \n * @param {AbortSignal} signal \n * @param {() => void} resolve \n */\nexport default function createLogin(signal, resolve) {\n\t// 创建表单\n\tconst form = document.createElement('form');\n\tconst title = form.appendChild(document.createElement('h2'));\n\ttitle.textContent = '用户登录';\n\tform.appendChild(title);\n\tconst store = Store.create(schema);\n\tstore.reset();\n\tif (signal.aborted) {\n\t\treturn null;\n\t}\n\n\n\trenderStoreForm(store, form, { editable: true, signal, layout });\n\n\t// 创建提交按钮\n\tconst submitButton = form.appendChild(document.createElement('button'));\n\tsubmitButton.type = 'submit';\n\tsubmitButton.textContent = '登录';\n\n\t// 添加事件监听器\n\tform.addEventListener('submit', async event => {\n\t\tevent.preventDefault();\n\t\tif (submitButton.disabled) { return; }\n\t\ttry {\n\t\t\tsubmitButton.disabled = true;\n\t\t\tconst { username, password, resetPassword, newPassword: { password1: newPassword } } = store.value;\n\t\t\tconst r = await store.validate();\n\t\t\tif (r?.length) { return; }\n\t\t\tconst result = await Plugin.request.clone().put().body({\n\t\t\t\tlogin: username, password, newPassword: resetPassword && newPassword || '',\n\t\t\t}).result();\n\t\t\tif (!result || typeof result === 'object') {\n\t\t\t\tresolve();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (result === 408) {\n\t\t\t\tconst resetPassword = store.child('resetPassword');\n\t\t\t\tif (resetPassword) { resetPassword.value = true; }\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (result === 404) {\n\t\t\t\talert('用户名错误');\n\t\t\t\tconst resetPassword = store.child('resetPassword');\n\t\t\t\tif (resetPassword) { resetPassword.value = false; }\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (result === 403) {\n\t\t\t\talert('用户名或密码错误');\n\t\t\t\tconst resetPassword = store.child('resetPassword');\n\t\t\t\tif (resetPassword) { resetPassword.value = false; }\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t} catch (e) {\n\t\t\tif (e instanceof Response) {\n\t\t\t\tif (e.status === 404) {\n\t\t\t\t\talert('用户名错误');\n\t\t\t\t} else if (e.status === 403) {\n\t\t\t\t\talert('密码错误');\n\t\t\t\t} else if (e.status === 408) {\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tsubmitButton.disabled = false;\n\t\t}\n\t});\n\n\treturn form;\n}\n","/** @import {Authenticator} from '@yongdall/web' */\nimport createLogin from './createLogin.mjs';\n\nconst root = document.createElement('div');\nroot.classList.add('yongdall-authenticator');\n\n/**@type {Partial<Authenticator>} */\nexport const authenticator = {\n\tstyleFiles: ['style.css'],\n\tclassNames: [],\n\telements: root,\n\tasync login(signal) {\n\t\t/** @type {PromiseWithResolvers<void>} */\n\t\tconst { promise, resolve } = Promise.withResolvers();\n\t\t/*** @type {Promise<void>} */\n\t\tconst signalPromise = new Promise(r => {\n\t\t\tif (signal.aborted) { r(); return; }\n\t\t\tsignal.addEventListener('abort', () => r(), { once: true });\n\t\t});\n\t\tconst form = createLogin(signal, resolve);\n\t\tif (!form) { return; }\n\t\troot.appendChild(form);\n\t\tawait Promise.race([promise, signalPromise])\n\t\t\t.finally(() => { form.remove(); });\n\t},\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@yongdall/authenticator",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "exports": {
5
5
  ".": "./assets/web.mjs"
6
6
  },
7
7
  "dependencies": {
8
- "@yongdall/http": "^0.1.0",
9
- "@yongdall/core": "^0.1.0"
8
+ "@yongdall/http": "^0.2.0",
9
+ "@yongdall/core": "^0.2.0"
10
10
  },
11
11
  "devDependencies": {
12
- "@yongdall/web": "^0.1.0"
12
+ "@yongdall/web": "^0.2.0"
13
13
  },
14
14
  "peerDependencies": {
15
- "@yongdall/web": "^0.1.0"
15
+ "@yongdall/web": "^0.2.0"
16
16
  },
17
17
  "main": "./assets/web.mjs",
18
18
  "type": "module"