@modernman00/shared-js-lib 1.2.13 → 1.2.23

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.
@@ -0,0 +1,53 @@
1
+ name: Release shared-js-lib
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ release:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout code
14
+ uses: actions/checkout@v3
15
+
16
+ - name: Setup Node.js
17
+ uses: actions/setup-node@v3
18
+ with:
19
+ node-version: '18'
20
+ registry-url: 'https://registry.npmjs.org/'
21
+ scope: '@modernman00'
22
+
23
+ - name: Install dependencies
24
+ run: npm ci
25
+
26
+ - name: Run tests
27
+ run: npm test
28
+
29
+ - name: Bump version and generate changelog
30
+ run: |
31
+ npm version patch -m "chore(release): %s"
32
+ npx auto-changelog -p
33
+ env:
34
+ GIT_AUTHOR_NAME: github-actions
35
+ GIT_AUTHOR_EMAIL: actions@github.com
36
+ GIT_COMMITTER_NAME: github-actions
37
+ GIT_COMMITTER_EMAIL: actions@github.com
38
+
39
+ - name: Push version bump and changelog
40
+ run: |
41
+ git push origin main --follow-tags
42
+
43
+ - name: Publish to npm
44
+ run: npm publish --access public
45
+ env:
46
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
47
+
48
+ - name: Create GitHub Release
49
+ uses: softprops/action-gh-release@v1
50
+ with:
51
+ tag_name: ${{ github.ref_name }}
52
+ env:
53
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,29 @@
1
+ name: Semantic Release
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ release:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout code
14
+ uses: actions/checkout@v3
15
+
16
+ - name: Setup Node.js
17
+ uses: actions/setup-node@v3
18
+ with:
19
+ node-version: '18'
20
+ registry-url: 'https://registry.npmjs.org/'
21
+
22
+ - name: Install dependencies
23
+ run: npm ci
24
+
25
+ - name: Run semantic-release
26
+ env:
27
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
28
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
29
+ run: npx semantic-release
@@ -0,0 +1,32 @@
1
+ name: Run Tests and Coverage
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - name: Checkout repo
15
+ uses: actions/checkout@v3
16
+
17
+ - name: Setup Node.js
18
+ uses: actions/setup-node@v3
19
+ with:
20
+ node-version: '20'
21
+
22
+ - name: Install dependencies
23
+ run: npm ci
24
+
25
+ - name: Run tests with coverage
26
+ run: npm test -- --coverage
27
+
28
+ - name: Upload coverage report
29
+ uses: actions/upload-artifact@v3
30
+ with:
31
+ name: coverage-report
32
+ path: coverage/
@@ -0,0 +1,90 @@
1
+ import { loginSubmission } from './processAll.js';
2
+ import { id } from '../UtilityHtml.js';
3
+ import { bindEvent } from '../Utility.js';
4
+ import { showPassword } from './loginUtility.js';
5
+ import { matchInput } from '../general.js';
6
+
7
+
8
+ /**
9
+ * Initializes password change functionality with accessibility, validation, and submission logic.
10
+ *
11
+ * This function sets up:
12
+ * - ARIA attributes for accessibility
13
+ * - Input matching between password and confirmation fields
14
+ * - Max length enforcement
15
+ * - Event bindings for submit and password visibility toggle
16
+ * - Form submission via `loginSubmission`
17
+ *
18
+ * @function setupPasswordChange
19
+ * @param {Object} [config] - Configuration object for customizing behavior.
20
+ * @param {string} [config.buttonId='button'] - ID of the submit button.
21
+ * @param {string} [config.passwordId='password_id'] - ID of the password input field.
22
+ * @param {string} [config.confirmId='confirm_password_id'] - ID of the confirm password input field.
23
+ * @param {string} [config.showToggleId='showPassword_id'] - ID of the toggle button to show/hide password.
24
+ * @param {string} [config.errorId='confirm_password_error'] - ID of the element to display mismatch errors.
25
+ * @param {string} [config.helpId='password_help'] - ID of the helper text element for password guidance.
26
+ * @param {string} [config.route] - API endpoint for password change submission.
27
+ * @param {string} [config.redirect] - URL to redirect to after successful password change.
28
+ * @param {string} [config.theme='bulma'] - UI theme identifier passed to `loginSubmission`.
29
+ * @param {number} [config.maxLength=50] - Maximum allowed length for password fields.
30
+ *
31
+ * @example
32
+ * setupPasswordChange(); // Uses default IDs and routes
33
+ *
34
+ * @example
35
+ * setupPasswordChange({
36
+ * buttonId: 'submitBtn',
37
+ * passwordId: 'new_password',
38
+ * confirmId: 'confirm_new_password',
39
+ * route: '/api/change-password',
40
+ * redirect: '/dashboard'
41
+ * });
42
+ */
43
+
44
+
45
+ export const setupPasswordChange = ({
46
+ buttonId = 'button',
47
+ passwordId = 'password_id',
48
+ confirmId = 'confirm_password_id',
49
+ showToggleId = 'showPassword_id',
50
+ errorId = 'confirm_password_error',
51
+ helpId = 'password_help',
52
+ route = "",
53
+ redirect = "",
54
+ theme = 'bulma',
55
+ maxLength = 50
56
+ } = {}) => {
57
+ // Accessibility & input attributes
58
+ const passwordInput = id(passwordId);
59
+ const confirmInput = id(confirmId);
60
+ const showToggle = id(showToggleId);
61
+ const helperText = id(helpId);
62
+
63
+ passwordInput.setAttribute('autocomplete', 'current-password');
64
+ showToggle.setAttribute('aria-label', 'Warning: this will display your password on the screen.');
65
+ helperText.setAttribute('aria-live', 'polite');
66
+ helperText.textContent =
67
+ 'Password must be at least 8 characters long, contain at least one uppercase letter, one lowercase letter, one number, and one special character.';
68
+
69
+ // Length limit object
70
+ const lengthLimit = {
71
+ maxLength: {
72
+ id: [passwordId, confirmId],
73
+ max: [maxLength, maxLength]
74
+ }
75
+ };
76
+
77
+ // Submission handler
78
+ const handleSubmit = (e) => {
79
+ e.preventDefault();
80
+ loginSubmission('changePassword', route, redirect, theme, lengthLimit);
81
+ };
82
+
83
+ // Bind events
84
+ bindEvent({ id: buttonId, handler: handleSubmit });
85
+ bindEvent({ id: showToggleId, handler: () => showPassword(passwordId) });
86
+ matchInput(passwordId, confirmId, errorId);
87
+ };
88
+
89
+
90
+
@@ -0,0 +1,50 @@
1
+ import { loginSubmission } from './processAll.js';
2
+ import { bindEvent } from '../Utility.js';
3
+
4
+ /**
5
+ * Creates a reusable form submission handler for code-based forms.
6
+ *
7
+ * @function createCodeSubmitHandler
8
+ * @param {Object} options - Configuration for the handler.
9
+ * @param {string} options.formId - ID of the form element.
10
+ * @param {string} options.inputId - ID of the input field to validate.
11
+ * @param {string} options.buttonId - ID of the submit button.
12
+ * @param {string} options.route - API endpoint for submission.
13
+ * @param {string} options.redirect - URL to redirect to after success.
14
+ * @param {string} [options.theme='bulma'] - UI theme identifier.
15
+ * @param {number} [options.maxLength=50] - Max input length.
16
+ *
17
+ * @example
18
+ * createCodeSubmitHandler({
19
+ * formId: 'codeForm',
20
+ * inputId: 'code_id',
21
+ * buttonId: 'button',
22
+ * route: appTestRoutes.appTestCode,
23
+ * redirect: appTestRoutes.appTestCodeRedirect
24
+ * });
25
+ */
26
+ export function createCodeSubmitHandler({
27
+ formId,
28
+ inputId,
29
+ buttonId,
30
+ route,
31
+ redirect,
32
+ theme = 'bulma',
33
+ maxLength = 50
34
+ }) {
35
+ const handler = (e) => {
36
+ e.preventDefault();
37
+
38
+ const lengthLimit = {
39
+ maxLength: {
40
+ id: [inputId],
41
+ max: [maxLength]
42
+ }
43
+ };
44
+
45
+ loginSubmission(formId, route, redirect, theme, lengthLimit);
46
+ };
47
+
48
+ bindEvent({ id: buttonId, handler });
49
+ }
50
+
@@ -0,0 +1,57 @@
1
+ import { loginSubmission} from './processAll.js';
2
+ import {bindEvent } from '../Utility.js';
3
+
4
+
5
+ /**
6
+ * Creates a reusable form submission handler for email-based forms.
7
+ *
8
+ * This function:
9
+ * - Prevents default form submission
10
+ * - Applies max length validation to the email input
11
+ * - Submits the form using `loginSubmission` with route and redirect logic
12
+ *
13
+ * @function createEmailSubmitHandler
14
+ * @param {Object} options - Configuration for the handler.
15
+ * @param {string} options.formId - ID of the form element.
16
+ * @param {string} options.inputId - ID of the email input field.
17
+ * @param {string} options.buttonId - ID of the submit button.
18
+ * @param {string} options.route - API endpoint for submission.
19
+ * @param {string} options.redirect - URL to redirect to after success.
20
+ * @param {string} [options.theme='bulma'] - UI theme identifier.
21
+ * @param {number} [options.maxLength=50] - Max input length.
22
+ *
23
+ * @example
24
+ * createEmailSubmitHandler({
25
+ * formId: 'forgotPassword',
26
+ * inputId: 'email_id',
27
+ * buttonId: 'button',
28
+ * route: appTestRoutes.appTestForgot,
29
+ * redirect: appTestRoutes.appTestForgotRedirect
30
+ * });
31
+ */
32
+ export function forgotSubmitHandler({
33
+ formId,
34
+ inputId,
35
+ buttonId,
36
+ route,
37
+ redirect,
38
+ theme = 'bulma',
39
+ maxLength = 50
40
+ }) {
41
+ const handler = (e) => {
42
+ e.preventDefault();
43
+
44
+ const lengthLimit = {
45
+ maxLength: {
46
+ id: [inputId],
47
+ max: [maxLength]
48
+ }
49
+ };
50
+
51
+ loginSubmission(formId, route, redirect, theme, lengthLimit);
52
+ };
53
+
54
+ bindEvent({ id: buttonId, handler });
55
+ }
56
+
57
+
@@ -0,0 +1,73 @@
1
+ import { loginSubmission } from './processAll.js';
2
+ import { id} from '../UtilityHtml.js';
3
+ import { bindEvent } from '../Utility.js';
4
+ import { showPassword } from './loginUtility.js';
5
+
6
+ /**
7
+ * Creates a reusable admin login handler with password visibility and accessibility support.
8
+ *
9
+ * This function:
10
+ * - Binds form submission to `loginSubmission`
11
+ * - Applies max length validation to email and password fields
12
+ * - Enables password visibility toggle
13
+ * - Sets accessibility attributes for screen readers and autocomplete
14
+ *
15
+ * @function createAdminLoginHandler
16
+ * @param {Object} options - Configuration for the login handler.
17
+ * @param {string} options.formId - ID of the login form.
18
+ * @param {string} options.emailId - ID of the email input field.
19
+ * @param {string} options.passwordId - ID of the password input field.
20
+ * @param {string} options.buttonId - ID of the submit button.
21
+ * @param {string} options.showToggleId - ID of the password visibility toggle button.
22
+ * @param {string} options.route - API endpoint for login submission.
23
+ * @param {string} options.redirect - URL to redirect to after successful login.
24
+ * @param {string} [options.theme='bootstrap'] - UI theme identifier.
25
+ * @param {number[]} [options.maxLength=[30, 50]] - Max lengths for password and email respectively.
26
+ *
27
+ * @example
28
+ * createAdminLoginHandler({
29
+ * formId: 'managed',
30
+ * emailId: 'email_id',
31
+ * passwordId: 'password_id',
32
+ * buttonId: 'button',
33
+ * showToggleId: 'showPassword_id',
34
+ * route: appTestRoutes.appTest,
35
+ * redirect: appTestRoutes.redirect
36
+ * });
37
+ */
38
+ export function createAdminLoginHandler({
39
+ formId,
40
+ emailId,
41
+ passwordId,
42
+ buttonId,
43
+ showToggleId,
44
+ route,
45
+ redirect,
46
+ theme = 'bootstrap',
47
+ maxLength = [30, 50]
48
+ }) {
49
+ const handler = (e) => {
50
+ e.preventDefault();
51
+
52
+ const lengthLimit = {
53
+ maxLength: {
54
+ id: [passwordId, emailId],
55
+ max: maxLength
56
+ }
57
+ };
58
+
59
+ loginSubmission(formId, route, redirect, theme, lengthLimit);
60
+ };
61
+
62
+ bindEvent({ id: buttonId, handler });
63
+ bindEvent({ id: showToggleId, handler: () => showPassword(passwordId) });
64
+
65
+ const passwordInput = id(passwordId);
66
+ const toggleLabel = id(showToggleId);
67
+
68
+ passwordInput.setAttribute('autocomplete', 'current-password');
69
+ toggleLabel.setAttribute(
70
+ 'aria-label',
71
+ 'Warning: this will display your password on the screen.'
72
+ );
73
+ }
@@ -0,0 +1,11 @@
1
+ import { id } from '../UtilityHtml.js';
2
+
3
+ export const showPassword = (inputId) => {
4
+ const y = id(inputId);
5
+ if (y.type === 'password') {
6
+
7
+ y.type = 'text';
8
+ } else {
9
+ y.type = 'password';
10
+ }
11
+ };
@@ -1,8 +1,9 @@
1
1
  'use strict';
2
- import { convertFormData } from './FormProcessing.js';
3
- import { postFormData } from './Http.js';
4
- import { showLoader, clearLoader } from './Loader.js';
5
- import { showError } from './ShowResponse.js';
2
+ import { postFormData } from '../Http.js';
3
+ import { showLoader, clearLoader } from '../Loader.js';
4
+ import { showError, qSel } from '../UtilityHtml.js';
5
+ import FormHelper from '../FormHelper.js';
6
+
6
7
 
7
8
  // block the setLoader div
8
9
 
@@ -15,28 +16,40 @@ import { showError } from './ShowResponse.js';
15
16
  * @returns {void}
16
17
  * @throws {Error} - If there is an error with the submission
17
18
  */
18
- export const loginSubmission = async (
19
- formId,
20
- loginURL,
21
- redirect,
22
- css = null, lengthLimit = null
19
+ export const loginSubmission = async (formId, loginURL, redirect, css = null, lengthLimit = null
23
20
  ) => {
24
- const formData = convertFormData(formId);
25
- formData.clearError();
26
- if (lengthLimit) {
27
- formData.realTimeCheckLen(lengthLimit.maxLength.id, lengthLimit.maxLength.max);
28
- }
29
21
 
30
22
  try {
31
- formData.emailVal();
32
- formData.massValidate();
33
23
 
34
- if (!formData.error.length) {
24
+ const formInput = qSel(`#${formId}`);
25
+
26
+ if (!formInput) {
27
+ throw new Error(`Form ${formId} not found`);
28
+ return;
29
+ }
30
+
31
+
32
+ const formInputArr = Array.from(formInput.elements);
33
+
34
+ const formData = new FormHelper(formInputArr);
35
+
36
+ formData.clearError();
37
+
38
+ if (lengthLimit) {
39
+ formData.realTimeCheckLen(lengthLimit.maxLength.id, lengthLimit.maxLength.max);
40
+ }
41
+
42
+ formData.massValidate([], { email: 'email', password: 'password' });
43
+
44
+ if (formData.result === 1) {
45
+
46
+
35
47
  showLoader();
36
48
  localStorage.setItem('redirect', redirect);
37
49
 
38
50
  await postFormData(loginURL, formId, redirect, css);
39
51
  } else {
52
+
40
53
  alert('The form cannot be submitted. Please check the errors');
41
54
  }
42
55
  } catch (err) {
package/Cookie.js CHANGED
@@ -47,3 +47,9 @@ export const checkCookie = (name) => {
47
47
  alert(`Welcome again ${user}`);
48
48
  }
49
49
  }
50
+
51
+ // CHECK TOKEN FROM COOKIE
52
+ export const getCookieValue = (name) => {
53
+ const match = document.cookie.split('; ').find(row => row.startsWith(name + '='));
54
+ return match ? decodeURIComponent(match.split('=')[1]) : null;
55
+ }
package/CountryCode.js CHANGED
@@ -4,7 +4,7 @@ import { id } from './UtilityHtml.js';
4
4
 
5
5
  // Object to map countries to country codes
6
6
 
7
- const countryCodes = {
7
+ export const countryCodes = {
8
8
  Afghanistan: '93',
9
9
  Albania: '355',
10
10
  Algeria: '213',
@@ -1,12 +1,5 @@
1
- import { qSelAll, id } from './UtilityHtml.js';
2
- import FormHelper from './FormHelper.js';
1
+ import { id } from './UtilityHtml.js';
3
2
 
4
- export const convertFormData = (formId) => {
5
- const formInput = qSelAll(formId)
6
- const formInputArr = Array.from(formInput)
7
- return new FormHelper(formInputArr)
8
-
9
- }
10
3
 
11
4
  /**
12
5
  * Sets up an event listener for the given button element that triggers a file upload click event.