@pixelated-tech/components 3.9.16 → 3.9.18

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.
@@ -6,8 +6,9 @@ import path from 'path';
6
6
  * Enforces workspace standards for SEO, performance, and project structure.
7
7
  */
8
8
 
9
- /* ===== CLIENT COMPONENT DETECTION (Copied from functions.ts for standalone usage) ===== */
10
- const CLIENT_ONLY_PATTERNS = [
9
+
10
+ // DUPLICATE FROM components/general/utilities.ts --- KEEP IN SYNC ---
11
+ export const CLIENT_ONLY_PATTERNS = [
11
12
  /\baddEventListener\b/,
12
13
  /\bcreateContext\b/,
13
14
  /\bdocument\./,
@@ -35,10 +36,11 @@ const CLIENT_ONLY_PATTERNS = [
35
36
  /["']use client["']/ // Client directive
36
37
  ];
37
38
 
38
- function isClientComponent(fileContent) {
39
+ export function isClientComponent(fileContent) {
39
40
  return CLIENT_ONLY_PATTERNS.some(pattern => pattern.test(fileContent));
40
41
  }
41
42
 
43
+
42
44
  const propTypesInferPropsRule = {
43
45
  meta: {
44
46
  type: 'problem',
@@ -372,6 +374,51 @@ const noRawImgRule = {
372
374
  },
373
375
  };
374
376
 
377
+ /* ===== RULE: require-section-ids ===== */
378
+ const requireSectionIdsRule = {
379
+ meta: {
380
+ type: 'suggestion',
381
+ docs: {
382
+ description: 'Require `id` attributes on every <section> and <PageSection> for jump links and SEO',
383
+ category: 'Accessibility',
384
+ recommended: false,
385
+ },
386
+ messages: {
387
+ missingId: '`section` and `PageSection` elements must have an `id` attribute for jump-link support and SEO hierarchy.',
388
+ },
389
+ schema: [],
390
+ },
391
+ create(context) {
392
+ /*
393
+ * Helper: get a string name for a JSX element. Supports
394
+ * `JSXIdentifier` and `JSXMemberExpression` (e.g. `UI.PageSection`).
395
+ */
396
+ function getJSXElementName(node) {
397
+ if (!node) return null;
398
+ if (node.type === 'JSXIdentifier') return node.name;
399
+ if (node.type === 'JSXMemberExpression') return node.property?.name || null;
400
+ return null;
401
+ }
402
+
403
+ return {
404
+ JSXOpeningElement(node) {
405
+ try {
406
+ const name = getJSXElementName(node.name); if (!name || !['section','PageSection'].includes(name)) return;
407
+
408
+ const hasId = (node.attributes || []).some(attr => (
409
+ attr.type === 'JSXAttribute' && attr.name && attr.name.name === 'id' && attr.value != null
410
+ ));
411
+ if (!hasId) {
412
+ context.report({ node, messageId: 'missingId' });
413
+ }
414
+ } catch (e) {
415
+ // defensive: don't crash lint
416
+ }
417
+ },
418
+ };
419
+ },
420
+ };
421
+
375
422
  const requiredFaqRule = {
376
423
  meta: {
377
424
  type: 'suggestion',
@@ -381,8 +428,8 @@ const requiredFaqRule = {
381
428
  recommended: true,
382
429
  },
383
430
  messages: {
384
- missingFaqPage: 'FAQ page is missing. FAQ pages are strongly recommended for every site (src/app/faq/page.tsx).',
385
- missingFaqSchema: 'FAQSchema is missing from the FAQ page.',
431
+ missingFaqPage: 'FAQ page is missing. FAQ pages are strongly recommended (examples: src/app/faqs/page.tsx, src/app/(pages)/faqs/page.tsx, src/pages/faqs/index.tsx).',
432
+ missingFaqSchema: 'FAQSchema (SchemaFAQ / JSON-LD @type:FAQPage) is missing from the FAQ page.',
386
433
  },
387
434
  },
388
435
  create(context) {
@@ -390,27 +437,76 @@ const requiredFaqRule = {
390
437
  if (!context.getFilename().endsWith('layout.tsx')) return {};
391
438
 
392
439
  const projectRoot = context.cwd;
393
- const faqPath = path.join(projectRoot, 'src/app/faq/page.tsx');
440
+
441
+ function findFaqPath(root) {
442
+ // Walk `src/` and match any path segment or filename named `faq` or `faqs`.
443
+ // Return the first matching `page.*` / `index.*` or a direct faq(s).(ts|tsx|js|jsx) file.
444
+ // Returns `null` when no candidate is found.
445
+ const srcRoot = path.join(root, 'src');
446
+ if (!fs.existsSync(srcRoot)) return null;
447
+
448
+ const stack = [srcRoot];
449
+ const filePattern = /(^|\/)faqs?\.(t|j)sx?$/i; // matches .../faq.tsx, .../faqs.js, etc.
450
+ while (stack.length) {
451
+ const cur = stack.pop();
452
+ try {
453
+ const entries = fs.readdirSync(cur, { withFileTypes: true });
454
+ for (const e of entries) {
455
+ const full = path.join(cur, e.name);
456
+ const rel = path.relative(root, full).replace(/\\/g, '/');
457
+
458
+ if (e.isDirectory()) {
459
+ // directory named faq/faqs -> prefer page/index inside it
460
+ if (/^faqs?$/i.test(e.name)) {
461
+ const candidates = [
462
+ path.join(full, 'page.tsx'),
463
+ path.join(full, 'page.ts'),
464
+ path.join(full, 'index.tsx'),
465
+ path.join(full, 'index.ts'),
466
+ ];
467
+ for (const c of candidates) if (fs.existsSync(c)) return c;
468
+ }
469
+ // continue walking
470
+ stack.push(full);
471
+ continue;
472
+ }
473
+
474
+ // direct file matches like src/pages/faqs.tsx
475
+ if (filePattern.test(rel)) return full;
476
+ }
477
+ } catch (err) {
478
+ /* ignore unreadable dirs */
479
+ }
480
+ }
481
+
482
+ return null;
483
+ }
484
+
485
+ const faqPath = findFaqPath(projectRoot);
394
486
 
395
487
  return {
396
488
  'Program:exit'() {
397
- if (!fs.existsSync(faqPath)) {
489
+ // If finder returned nothing or the candidate does not exist -> missing page
490
+ if (!faqPath || !fs.existsSync(faqPath)) {
398
491
  context.report({
399
492
  loc: { line: 1, column: 0 },
400
493
  messageId: 'missingFaqPage',
401
494
  });
402
- } else {
403
- try {
404
- const content = fs.readFileSync(faqPath, 'utf8');
405
- if (!content.includes('FAQSchema')) {
406
- context.report({
407
- loc: { line: 1, column: 0 },
408
- messageId: 'missingFaqSchema',
409
- });
410
- }
411
- } catch (e) {
412
- // Ignore read errors
495
+ return;
496
+ }
497
+
498
+ // Accept component-based SchemaFAQ, `FAQSchema` identifier, or JSON-LD @type:FAQPage
499
+ try {
500
+ const content = fs.readFileSync(faqPath, 'utf8');
501
+ const hasSchema = /FAQSchema|SchemaFAQ|"@type"\s*:\s*"FAQPage"/i.test(content);
502
+ if (!hasSchema) {
503
+ context.report({
504
+ loc: { line: 1, column: 0 },
505
+ messageId: 'missingFaqSchema',
506
+ });
413
507
  }
508
+ } catch (e) {
509
+ // Ignore read errors
414
510
  }
415
511
  },
416
512
  };
@@ -423,6 +519,7 @@ export default {
423
519
  'required-schemas': requiredSchemasRule,
424
520
  'required-files': requiredFilesRule,
425
521
  'no-raw-img': noRawImgRule,
522
+ 'require-section-ids': requireSectionIdsRule,
426
523
  'required-faq': requiredFaqRule,
427
524
  },
428
525
  configs: {
@@ -432,6 +529,7 @@ export default {
432
529
  'pixelated/required-schemas': 'warn',
433
530
  'pixelated/required-files': 'warn',
434
531
  'pixelated/no-raw-img': 'warn',
532
+ 'pixelated/require-section-ids': 'warn',
435
533
  'pixelated/required-faq': 'warn',
436
534
  },
437
535
  },
@@ -38,20 +38,58 @@ fi
38
38
  echo ""
39
39
  echo "🔑 Step $((STEP_COUNT++)): Choose the git Remote to release:"
40
40
  echo "================================================="
41
- # Function to prompt for remote selection
41
+ # Helper: derive a sensible default remote (remote whose repo name matches local folder)
42
+ derive_default_remote() {
43
+ local remotes=($(git remote))
44
+ local local_repo
45
+ local_repo=$(basename "$(git rev-parse --show-toplevel)")
46
+ for remote in "${remotes[@]}"; do
47
+ url=$(git remote get-url "$remote" 2>/dev/null || true)
48
+ repo=$(basename -s .git "${url##*/}")
49
+ if [ -n "$repo" ] && [ "$repo" = "$local_repo" ]; then
50
+ echo "$remote"
51
+ return
52
+ fi
53
+ done
54
+ # Fallback to first remote if no match
55
+ echo "${remotes[0]}"
56
+ }
57
+
58
+ # Function to prompt for remote selection, showing a default derived from local repo name
42
59
  prompt_remote_selection() {
43
60
  echo "Available git remotes:" >&2
44
61
  local remotes=($(git remote))
62
+ local count=${#remotes[@]}
45
63
  local i=1
64
+
46
65
  for remote in "${remotes[@]}"; do
47
66
  echo "$i) $remote" >&2
48
67
  ((i++))
49
68
  done
69
+
70
+ local default_remote
71
+ default_remote=$(derive_default_remote)
72
+ # find index of default_remote for user prompt
73
+ local default_index=1
74
+ for idx in "${!remotes[@]}"; do
75
+ if [ "${remotes[$idx]}" = "$default_remote" ]; then
76
+ default_index=$((idx+1))
77
+ break
78
+ fi
79
+ done
80
+
81
+ local prompt="Select remote to use (1-$count) [default $default_index - $default_remote]: "
50
82
  local choice
51
- read -p "Select remote to use (1-${#remotes[@]}): " choice >&2
83
+ read -p "$prompt" choice >&2
84
+
85
+ if [ -z "$choice" ]; then
86
+ echo "$default_remote"
87
+ return
88
+ fi
89
+
52
90
  case $choice in
53
91
  [1-9]|[1-9][0-9])
54
- if [ "$choice" -le "${#remotes[@]}" ]; then
92
+ if [ "$choice" -le "$count" ]; then
55
93
  echo "${remotes[$((choice-1))]}"
56
94
  else
57
95
  echo "${remotes[0]}" # Default to first if invalid
@@ -213,7 +251,13 @@ prompt_version_type() {
213
251
  echo "3) major (1.x.x)" >&2
214
252
  echo "4) custom version" >&2
215
253
  echo "5) no version bump" >&2
216
- read -p "Enter choice (1-5): " choice >&2
254
+ read -p "Enter choice (1-5) [default 1]: " choice >&2
255
+
256
+ # Default to 1 (patch) when user presses Enter
257
+ if [ -z "$choice" ]; then
258
+ choice=1
259
+ fi
260
+
217
261
  case $choice in
218
262
  1) version_type="patch" ;;
219
263
  2) version_type="minor" ;;
@@ -223,7 +267,7 @@ prompt_version_type() {
223
267
  version_type="$custom_version"
224
268
  ;;
225
269
  5) version_type="none" ;;
226
- *) version_type="patch" ;; # default
270
+ *) version_type="patch" ;; # fallback default
227
271
  esac
228
272
  }
229
273
  prompt_version_type
@@ -13,6 +13,7 @@ echo "Base directory: $BASE_DIR"
13
13
  REPOS=(
14
14
  "brianwhaley"
15
15
  "informationfocus"
16
+ "leadscraper"
16
17
  "oaktreelandscaping"
17
18
  "palmetto-epoxy"
18
19
  "pixelated"
@@ -43,16 +44,40 @@ for repo in "${REPOS[@]}"; do
43
44
  echo "Configuring remotes for: $repo"
44
45
  cd "$repo_path"
45
46
 
46
- # Add remotes for all repositories
47
- for target_repo in "${REPOS[@]}"; do
48
- echo " - Setting up $target_repo remote"
49
- remote_url="https://github.com/$GITHUB_USER/$target_repo.git"
50
- # Remove remote if it exists, then add fresh
51
- git remote remove "$target_repo" 2>/dev/null || true
52
- git remote add "$target_repo" "$remote_url"
53
- done
54
-
55
- echo " ✓ All remotes configured for $repo"
47
+ if [ "$repo" = "pixelated-components" ]; then
48
+ # Pixelated-components should have remotes for ALL repos
49
+ for target_repo in "${REPOS[@]}"; do
50
+ remote_url="https://github.com/$GITHUB_USER/$target_repo.git"
51
+ if git remote | grep -q "^$target_repo$"; then
52
+ git remote set-url "$target_repo" "$remote_url" 2>/dev/null || true
53
+ else
54
+ git remote add "$target_repo" "$remote_url" 2>/dev/null || true
55
+ fi
56
+ done
57
+ echo " ✓ pixelated-components configured with all remotes"
58
+ else
59
+ # Non-components repos should have only their own remote named after the repo
60
+ desired_remote="$repo"
61
+ desired_url="https://github.com/$GITHUB_USER/$repo.git"
62
+
63
+ # Ensure desired remote exists and points to the correct URL
64
+ if git remote | grep -q "^$desired_remote$"; then
65
+ git remote set-url "$desired_remote" "$desired_url" 2>/dev/null || true
66
+ else
67
+ git remote add "$desired_remote" "$desired_url" 2>/dev/null || true
68
+ fi
69
+
70
+ # Remove direct-name remotes that are other pixelated repos (avoid touching unrelated remotes)
71
+ for other in "${REPOS[@]}"; do
72
+ if [ "$other" != "$repo" ] && git remote | grep -q "^$other$"; then
73
+ echo " - Removing stray remote $other from $repo"
74
+ git remote remove "$other" 2>/dev/null || true
75
+ fi
76
+ done
77
+
78
+ echo " ✓ $repo configured with its own remote only"
79
+ fi
80
+
56
81
  else
57
82
  echo "⚠️ Skipping $repo (not a Git repository or doesn't exist)"
58
83
  fi
@@ -1,6 +1,6 @@
1
1
  import fs from 'fs';
2
2
  import glob from 'glob';
3
- import { CLIENT_ONLY_PATTERNS, TS_FILE_IGNORE_PATTERNS, TSX_FILE_IGNORE_PATTERNS, SERVER_ONLY_PATTERNS } from '../components/general/utilities.js';
3
+ import { CLIENT_ONLY_PATTERNS, TS_FILE_IGNORE_PATTERNS, TSX_FILE_IGNORE_PATTERNS, SERVER_ONLY_PATTERNS } from '../components/general/utilities';
4
4
 
5
5
  console.log('🔍 Validating exports...\n');
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"faq-accordion.d.ts","sourceRoot":"","sources":["../../../../src/components/general/faq-accordion.tsx"],"names":[],"mappings":"AACA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,qBAAqB,CAAC;AA8B7B,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;AACzE,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE,gBAAgB,2CAsF1D;yBAtFe,YAAY"}
1
+ {"version":3,"file":"faq-accordion.d.ts","sourceRoot":"","sources":["../../../../src/components/general/faq-accordion.tsx"],"names":[],"mappings":"AACA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,qBAAqB,CAAC;AA+B7B,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;AACzE,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE,gBAAgB,2CAuF1D;yBAvFe,YAAY"}
@@ -7,6 +7,7 @@ export declare namespace Tiles {
7
7
  var propTypes: {
8
8
  cards: PropTypes.Validator<any[]>;
9
9
  rowCount: PropTypes.Requireable<number>;
10
+ imgClick: PropTypes.Requireable<(...args: any[]) => any>;
10
11
  };
11
12
  }
12
13
  export type TileType = InferProps<typeof Tile.propTypes>;
@@ -19,6 +20,7 @@ declare namespace Tile {
19
20
  image: PropTypes.Validator<string>;
20
21
  imageAlt: PropTypes.Requireable<string>;
21
22
  bodyText: PropTypes.Requireable<string>;
23
+ imgClick: PropTypes.Requireable<(...args: any[]) => any>;
22
24
  };
23
25
  }
24
26
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"tiles.d.ts","sourceRoot":"","sources":["../../../../src/components/general/tiles.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAKnD,OAAO,+BAA+B,CAAC;AACvC,OAAO,aAAa,CAAC;AAOrB,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC;AAC3D,wBAAgB,KAAK,CAAC,KAAK,EAAE,SAAS,2CA0BrC;yBA1Be,KAAK;;;;;;AAuCrB,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC;AACzD,iBAAS,IAAI,CAAE,KAAK,EAAE,QAAQ,2CAuB7B;kBAvBQ,IAAI"}
1
+ {"version":3,"file":"tiles.d.ts","sourceRoot":"","sources":["../../../../src/components/general/tiles.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAKnD,OAAO,+BAA+B,CAAC;AACvC,OAAO,aAAa,CAAC;AAQrB,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC;AAC3D,wBAAgB,KAAK,CAAC,KAAK,EAAE,SAAS,2CA2BrC;yBA3Be,KAAK;;;;;;;AAyCrB,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC;AACzD,iBAAS,IAAI,CAAE,KAAK,EAAE,QAAQ,2CAyB7B;kBAzBQ,IAAI"}
@@ -18,12 +18,6 @@ export declare function logAllChange(): void;
18
18
  * Used by both ESLint rules and build scripts to determine client vs server components
19
19
  */
20
20
  export declare const CLIENT_ONLY_PATTERNS: RegExp[];
21
- /**
22
- * Determines if a component file contains client-only code that requires browser execution
23
- * @param fileContent - The source code content of the file
24
- * @returns true if the file contains client-only patterns
25
- */
26
- export declare function isClientComponent(fileContent: string): boolean;
27
21
  /**
28
22
  * Glob patterns for finding component files
29
23
  */
@@ -1 +1 @@
1
- {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../../../src/components/general/utilities.ts"],"names":[],"mappings":"AAGA,wBAAgB,QAAQ,CAAE,GAAG,EAAE,MAAM,oBAUpC;AAGD,wBAAgB,SAAS,CAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;;EAmBxC;AAED,wBAAgB,aAAa,CAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAOtD;AAED,wBAAgB,WAAW,WAc1B;AAED,wBAAgB,YAAY,WAK3B;AAED,wBAAgB,UAAU,CAAE,GAAG,EAAE,MAAM,UAEtC;AAQD,wBAAgB,YAAY,CAAE,YAAY,EAAE,MAAM,UAgCjD;AAID;;;;OAII;AACJ,wBAAgB,YAAY,SAoB3B;AAKD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,UA0BhC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE9D;AAGD;;GAEG;AACH,eAAO,MAAM,uBAAuB,UAQnC,CAAC;AAEF,eAAO,MAAM,wBAAwB,UAOpC,CAAC;AAGF;;GAEG;AACH,eAAO,MAAM,oBAAoB,UAoBhC,CAAC"}
1
+ {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../../../src/components/general/utilities.ts"],"names":[],"mappings":"AAGA,wBAAgB,QAAQ,CAAE,GAAG,EAAE,MAAM,oBAUpC;AAGD,wBAAgB,SAAS,CAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG;;EAmBxC;AAED,wBAAgB,aAAa,CAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAOtD;AAED,wBAAgB,WAAW,WAc1B;AAED,wBAAgB,YAAY,WAK3B;AAED,wBAAgB,UAAU,CAAE,GAAG,EAAE,MAAM,UAEtC;AAQD,wBAAgB,YAAY,CAAE,YAAY,EAAE,MAAM,UAgCjD;AAID;;;;OAII;AACJ,wBAAgB,YAAY,SAoB3B;AAOD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,UA0BhC,CAAC;AAGF;;GAEG;AACH,eAAO,MAAM,uBAAuB,UAQnC,CAAC;AAEF,eAAO,MAAM,wBAAwB,UAOpC,CAAC;AAGF;;GAEG;AACH,eAAO,MAAM,oBAAoB,UAoBhC,CAAC"}
@@ -4,7 +4,12 @@ export function copyTemplateForPage(templatePathArg: any, templateSrc: any, temp
4
4
  used: string;
5
5
  src: any;
6
6
  }>;
7
- export function createAndPushRemote(destPath: any, siteName: any, defaultOwner: any): Promise<void>;
7
+ export function createAndPushRemote(destPath: any, siteName: any, defaultOwner: any): Promise<{
8
+ cloneUrl: any;
9
+ remoteName: any;
10
+ token: any;
11
+ }>;
12
+ export function createAmplifyApp(rl: any, siteName: any, cloneUrl: any, sitePath: any): Promise<void>;
8
13
  export let _exec: typeof execCb.__promisify__;
9
14
  export namespace TOKEN_MAP {
10
15
  let __SITE_NAME__: string;
@@ -1 +1 @@
1
- {"version":3,"file":"create-pixelated-app.d.ts","sourceRoot":"","sources":["../../../src/scripts/create-pixelated-app.js"],"names":[],"mappings":";AA8MA,+GAaC;AAID;;;GAUC;AAGD,oGAyGC;AAnQD,8CAAwB;;;;;;+BAZO,eAAe"}
1
+ {"version":3,"file":"create-pixelated-app.d.ts","sourceRoot":"","sources":["../../../src/scripts/create-pixelated-app.js"],"names":[],"mappings":";AAyLA,+GAaC;AAID;;;GAUC;AAGD;;;;GA2HC;AAKD,sGAoIC;AA9ZD,8CAAwB;;;;;;+BAfO,eAAe"}
@@ -1,3 +1,9 @@
1
+ export function isClientComponent(fileContent: any): boolean;
2
+ /**
3
+ * Pixelated ESLint Plugin
4
+ * Enforces workspace standards for SEO, performance, and project structure.
5
+ */
6
+ export const CLIENT_ONLY_PATTERNS: RegExp[];
1
7
  declare namespace _default {
2
8
  let rules: {
3
9
  'prop-types-inferprops': {
@@ -80,6 +86,23 @@ declare namespace _default {
80
86
  JSXOpeningElement(node: any): void;
81
87
  };
82
88
  };
89
+ 'require-section-ids': {
90
+ meta: {
91
+ type: string;
92
+ docs: {
93
+ description: string;
94
+ category: string;
95
+ recommended: boolean;
96
+ };
97
+ messages: {
98
+ missingId: string;
99
+ };
100
+ schema: never[];
101
+ };
102
+ create(context: any): {
103
+ JSXOpeningElement(node: any): void;
104
+ };
105
+ };
83
106
  'required-faq': {
84
107
  meta: {
85
108
  type: string;
@@ -107,6 +130,7 @@ declare namespace _default {
107
130
  'pixelated/required-schemas': string;
108
131
  'pixelated/required-files': string;
109
132
  'pixelated/no-raw-img': string;
133
+ 'pixelated/require-section-ids': string;
110
134
  'pixelated/required-faq': string;
111
135
  };
112
136
  export { rules_1 as rules };
@@ -1 +1 @@
1
- {"version":3,"file":"pixelated-eslint-plugin.d.ts","sourceRoot":"","sources":["../../../src/scripts/pixelated-eslint-plugin.js"],"names":[],"mappings":""}
1
+ {"version":3,"file":"pixelated-eslint-plugin.d.ts","sourceRoot":"","sources":["../../../src/scripts/pixelated-eslint-plugin.js"],"names":[],"mappings":"AAsCA,6DAEC;AArCD;;;GAGG;AAIH,4CA0BE"}
@@ -1 +1 @@
1
- {"version":3,"file":"config-vault.test.d.ts","sourceRoot":"","sources":["../../../src/tests/config-vault.test.js"],"names":[],"mappings":""}
1
+ {"version":3,"file":"config-vault.test.d.ts","sourceRoot":"","sources":["../../../src/tests/config-vault.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=required-faq.rule.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"required-faq.rule.test.d.ts","sourceRoot":"","sources":["../../../src/tests/required-faq.rule.test.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixelated-tech/components",
3
- "version": "3.9.16",
3
+ "version": "3.9.18",
4
4
  "private": false,
5
5
  "author": {
6
6
  "name": "Pixelated Technologies",
@@ -63,6 +63,7 @@
63
63
  "validate-exports": "npx tsx src/scripts/validate-exports.js",
64
64
  "copy2brianwhaley": "rm -rf ../brianwhaley/node_modules/@pixelated-tech/components/dist && cp -r dist ../brianwhaley/node_modules/@pixelated-tech/components/",
65
65
  "copy2informationfocus": "rm -rf ../informationfocus/node_modules/@pixelated-tech/components/dist && cp -r dist ../informationfocus/node_modules/@pixelated-tech/components/",
66
+ "copy2jzhomeimprovement": "rm -rf ../jz-home-improvement/node_modules/@pixelated-tech/components/dist && cp -r dist ../jz-home-improvement/node_modules/@pixelated-tech/components/",
66
67
  "copy2oaktreelandscaping": "rm -rf ../oaktreelandscaping/node_modules/@pixelated-tech/components/dist && cp -r dist ../oaktreelandscaping/node_modules/@pixelated-tech/components/",
67
68
  "copy2palmettoepoxy": "rm -rf ../palmetto-epoxy/node_modules/@pixelated-tech/components/dist && cp -r dist ../palmetto-epoxy/node_modules/@pixelated-tech/components/",
68
69
  "copy2pixelated": "rm -rf ../pixelated/node_modules/@pixelated-tech/components/dist && cp -r dist ../pixelated/node_modules/@pixelated-tech/components/",
@@ -70,7 +71,7 @@
70
71
  "copy2pixelatedtest": "rm -rf ../pixelated-test/node_modules/@pixelated-tech/components/dist && cp -r dist ../pixelated-test/node_modules/@pixelated-tech/components/",
71
72
  "copy2template": "rm -rf ../pixelated-template/node_modules/@pixelated-tech/components/dist && cp -r dist ../pixelated-template/node_modules/@pixelated-tech/components/",
72
73
  "copy2pixelatedadmin": "rm -rf ../pixelated-admin/node_modules/@pixelated-tech/components/dist && cp -r dist ../pixelated-admin/node_modules/@pixelated-tech/components/",
73
- "copy2all": "npm run copy2brianwhaley && npm run copy2informationfocus && npm run copy2oaktreelandscaping && npm run copy2palmettoepoxy && npm run copy2pixelated && npm run copy2pixelvivid && npm run copy2template && npm run copy2pixelatedadmin",
74
+ "copy2all": "npm run copy2brianwhaley && npm run copy2informationfocus && npm run copy2jzhomeimprovement && npm run copy2oaktreelandscaping && npm run copy2palmettoepoxy && npm run copy2pixelated && npm run copy2pixelvivid && npm run copy2template && npm run copy2pixelatedadmin",
74
75
  "storybook": "rm -rf node_modules/.cache && storybook dev -p 6006",
75
76
  "buildStorybook": "rm -rf node_modules/.cache && NODE_OPTIONS=\"--max-old-space-size=4096\" storybook build",
76
77
  "test": "vitest",
@@ -106,6 +107,8 @@
106
107
  "html-entities": "^2.6.0"
107
108
  },
108
109
  "devDependencies": {
110
+ "@aws-sdk/client-amplify": "^3.971.0",
111
+ "@aws-sdk/client-iam": "^3.971.0",
109
112
  "@babel/cli": "^7.28.6",
110
113
  "@babel/core": "^7.28.6",
111
114
  "@babel/plugin-proposal-class-properties": "^7.18.6",
@@ -119,15 +122,15 @@
119
122
  "@storybook/preset-scss": "^1.0.3",
120
123
  "@storybook/react-webpack5": "^10.1.11",
121
124
  "@testing-library/dom": "^10.4.1",
122
- "@testing-library/react": "^16.3.1",
125
+ "@testing-library/react": "^16.3.2",
123
126
  "@testing-library/user-event": "^14.6.1",
124
127
  "@types/md5": "^2.3.6",
125
128
  "@types/node": "^25.0.9",
126
129
  "@types/prop-types": "^15.7.15",
127
130
  "@types/react": "^19.2.8",
128
131
  "@types/react-dom": "^19.2.3",
129
- "@typescript-eslint/eslint-plugin": "^8.53.0",
130
- "@typescript-eslint/parser": "^8.53.0",
132
+ "@typescript-eslint/eslint-plugin": "^8.53.1",
133
+ "@typescript-eslint/parser": "^8.53.1",
131
134
  "@vitejs/plugin-react": "^5.1.2",
132
135
  "@vitest/coverage-v8": "^4.0.17",
133
136
  "@vitest/ui": "^4.0.17",
@@ -146,7 +149,7 @@
146
149
  "eslint-plugin-react": "^7.37.4",
147
150
  "eslint-plugin-storybook": "^10.1.11",
148
151
  "file-loader": "^6.2.0",
149
- "happy-dom": "^20.3.1",
152
+ "happy-dom": "^20.3.3",
150
153
  "jsdom": "^27.4.0",
151
154
  "less-loader": "^12.3.0",
152
155
  "mini-css-extract-plugin": "^2.10.0",