@autobusal/utilities 1.5.4 → 1.6.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.
@@ -34,7 +34,18 @@
34
34
  import { readdirSync, readFileSync, statSync } from 'node:fs';
35
35
  import { join } from 'node:path';
36
36
 
37
- const OPEN = /styled(?:\.\w+|\([^)]*\))(?:<[^>]*>)?`/g;
37
+ /*
38
+ * Claude - 2026-08-30: `css` was missing from this, and the miss was not
39
+ * theoretical - magus's own `columnStyles = css<{...}>\`` carried a comment
40
+ * quoting a theme token in backticks, this script reported "clean", and the
41
+ * build then failed with a parse error pointing somewhere else entirely.
42
+ *
43
+ * A shared `css` block is the same template literal as `styled.x` and
44
+ * breaks in exactly the same way, so it has to be scanned the same way.
45
+ * `keyframes` and `createGlobalStyle` are here for the same reason before
46
+ * somebody finds them the hard way.
47
+ */
48
+ const OPEN = /(?:styled(?:\.\w+|\([^)]*\))|css|keyframes|createGlobalStyle)(?:<[^>]*>)?`/g;
38
49
 
39
50
  const walk = (dir) => readdirSync(dir).flatMap((entry) => {
40
51
  const path = join(dir, entry);
package/date.tsx CHANGED
@@ -6,6 +6,43 @@ export const createDate = (prepared: string): Date => {
6
6
  return new Date(Date.UTC(Number(data[2]), Number(data[1]) - 1, Number(data[0])));
7
7
  };
8
8
 
9
+ /**
10
+ * Whether a string is a d/m/Y date this app can actually work with.
11
+ *
12
+ * Claude - Date: 2026-08-29
13
+ *
14
+ * `createDate` splits on "/" and feeds the pieces to Date.UTC, so anything
15
+ * that is not a date at all produces an Invalid Date rather than an error -
16
+ * and a calendar built from one renders January of nothing. The literal
17
+ * "none" the search URL carries for "no return leg" is exactly that, which
18
+ * is how the round-trip picker came to open on January instead of the
19
+ * outbound's month.
20
+ */
21
+ export const isPreparedDate = (value?: string | null): boolean => {
22
+ if (!value) {
23
+ return false;
24
+ }
25
+
26
+ const parts = value.split('/');
27
+
28
+ if (parts.length !== 3) {
29
+ return false;
30
+ }
31
+
32
+ const [ day, month, year ] = parts.map(Number);
33
+
34
+ if (!day || !month || !year) {
35
+ return false;
36
+ }
37
+
38
+ const date = new Date(Date.UTC(year, month - 1, day));
39
+
40
+ // round-trips through Date so 31/02/2026 is refused as well as "none"
41
+ return date.getUTCFullYear() === year
42
+ && date.getUTCMonth() === month - 1
43
+ && date.getUTCDate() === day;
44
+ };
45
+
9
46
  export const prepareDate = (date: Date): string => {
10
47
  const day = date.getDate();
11
48
  const month = date.getMonth() + 1;
package/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { createDate, prepareDate, getFormattedShort, getDayParts, differenceYears, futureDate } from './date';
1
+ import { createDate, prepareDate, isPreparedDate, getFormattedShort, getDayParts, differenceYears, futureDate } from './date';
2
2
  import { Validate, Display } from './form';
3
3
  import { error, notify, success } from './notify';
4
4
  import { getAllowed, getLanguages, getPayments } from './options';
@@ -17,6 +17,7 @@ export {
17
17
  success,
18
18
  createDate,
19
19
  prepareDate,
20
+ isPreparedDate,
20
21
  getFormattedShort,
21
22
  getDayParts,
22
23
  differenceYears,
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@autobusal/utilities",
3
- "version": "1.5.4",
3
+ "version": "1.6.0",
4
4
  "author": "Ferjolt Ozuni",
5
5
  "type": "module",
6
6
  "main": "index.ts",
7
7
  "dependencies": {
8
8
  "dompurify": "^3.4.14"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public"
9
12
  }
10
13
  }
package/CHANGELOG.md DELETED
@@ -1,79 +0,0 @@
1
- # Changelog
2
-
3
- ## 1.5.4 (2026-08-28)
4
-
5
- - DisplayStatus renders status 4 (awaiting approval) as a badge instead of a blank cell in the admin agent/visitor/API-consumer lists (sweep #61).
6
-
7
- ## 1.5.3
8
-
9
- ### Fixed
10
-
11
- - **The backtick guard tripped on prose about styled-components**, and was refusing to publish the whole repo. Its opening pattern matches `styled.x` followed by a backtick as *text*, so a JSDoc line describing another file - "labels as `<span>` (Viewer/styles.ts: `Label = styled.span`)" - opened a template no code had opened, and every comment up to the next `` `; `` in the file counted as inside it. A comment about the hazard tripping the guard against the hazard. Openings found inside comments are now ignored; backticks inside comments, which are the thing being hunted, still are not.
12
-
13
- ## 1.5.2
14
-
15
- ### Changed
16
-
17
- - DOMPurify raised to `^3.4.14` for GHSA-55q2-fjhq-7xh7. It rates as moderate, which understates it here: DOMPurify is what `sanitizeHtml` is, so it sits directly on the path every piece of admin-authored and model-generated HTML takes before reaching a browser.
18
-
19
- ## 1.5.1
20
-
21
- ### Changed
22
-
23
- - **`error` collapses repeats into one toast** - it now raises the toast
24
- under an id, defaulting to the message itself, so a page whose parallel
25
- queries all fail the same way shows one red box rather than a stack of
26
- identical ones. Existing call sites need no change. A repeat of the same
27
- failure once the toast has gone still raises a fresh one.
28
-
29
- ## 1.5.0
30
-
31
- ### Added
32
-
33
- - **`GetStatus` knows status 4, "awaiting approval"** - distinct from 3
34
- (pending, waiting on the account to finish its own form) and from 2
35
- (suspended, a decision already taken against it).
36
-
37
-
38
- ## 1.4.1
39
-
40
- ### Changed
41
-
42
- - **Gender can be "not declared".** `getOptionsSex` gains it as the first
43
- option and `getSex` reports it, instead of treating everything that is not
44
- `1` as male — which is what three existing rows with no value were already
45
- rendering as.
46
-
47
- Carried by `null`: the `visitors`.`sex` column has always been nullable, so
48
- nothing migrated. The option's id is `''`, which Laravel's
49
- `ConvertEmptyStringsToNull` turns into a real null on the way in, so "not
50
- declared" is the *absence* of a value at every layer rather than a magic
51
- number each one has to learn.
52
-
53
- Deliberately not shared with the checkout passenger forms — those build
54
- their own field, and gender there is a per-route requirement a carrier can
55
- insist on. A profile is the person; a passenger record is what a carrier
56
- demands in order to board them.
57
-
58
- ## 1.4.0
59
-
60
- ### Added
61
-
62
- - **`check-backticks.mjs`**, moved here from the autobusal repo root so the
63
- apps can run it too.
64
-
65
- A backtick used as quoting inside a styled-components template *terminates
66
- the template*. The bundler then reports a syntax error somewhere further
67
- down, pointing at a line that is perfectly fine — so the search starts in
68
- the wrong place every time. Per the script's own history that cost five
69
- build failures in one session before anyone connected the two.
70
-
71
- It only ever guarded `packages`, and the trap is not confined there: it bit
72
- `magus/src` the moment a public page grew its own styled-components, with
73
- nothing watching. Each app's `prebuild` now runs it over its own `src`
74
- (first, so a broken template stops the build before it spends minutes
75
- copying files), and `publish.sh` still runs it over `packages`.
76
-
77
- One script with three callers, rather than a copy per repo that drifts.
78
-
79
- Takes the directory to scan as its argument.