@adaptive-sm/astro-ui 0.2.1 → 0.3.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.
Files changed (92) hide show
  1. package/README.md +7 -7
  2. package/lib/badge/Badge.astro +27 -0
  3. package/lib/badge/classesBadge.ts +67 -0
  4. package/lib/button/Button.astro +17 -27
  5. package/lib/button/buttonCva.ts +2 -2
  6. package/lib/button/buttonIconCva.ts +2 -2
  7. package/lib/button/classesButtonClickAnimation.ts +1 -1
  8. package/lib/button/classesButtonClickAnimationPush.ts +1 -1
  9. package/lib/button/classesButtonClickAnimationSquish.ts +1 -1
  10. package/lib/card/CardWrapper.astro +6 -5
  11. package/lib/card/classesBorderWrapper.ts +1 -0
  12. package/lib/card/classesCardWrapper.ts +21 -9
  13. package/lib/card/classesShadow.ts +5 -0
  14. package/lib/details/Details.astro +13 -8
  15. package/lib/dev/TailwindIndicator.astro +2 -2
  16. package/lib/form/Fieldset.astro +8 -5
  17. package/lib/generate_demo_list/DemoList.astro +3 -3
  18. package/lib/generate_demo_list/generateDemoList.ts +2 -2
  19. package/lib/generate_image_list/generateImageList.ts +3 -3
  20. package/lib/grid/FeatureGridSection.astro +28 -35
  21. package/lib/grid/classesGridCols.ts +27 -2
  22. package/lib/header/PageHeader.astro +25 -0
  23. package/lib/header/SectionHeader.astro +37 -0
  24. package/lib/icon/Icon.astro +26 -0
  25. package/lib/icons/iconGithub.ts +4 -0
  26. package/lib/icons/iconGoogle.ts +4 -0
  27. package/lib/icons/iconLinkedin.ts +2 -0
  28. package/lib/icons/iconNpm.ts +2 -0
  29. package/lib/icons/iconTelegram.ts +2 -0
  30. package/lib/icons/iconTrello.ts +2 -0
  31. package/lib/icons/iconXcom.ts +1 -0
  32. package/lib/img/Img.astro +8 -5
  33. package/lib/img/TypedImg.astro +9 -10
  34. package/lib/img/TypedImgB2.astro +23 -0
  35. package/lib/layouts/MarkdownPageWrapper.astro +19 -0
  36. package/lib/layouts/MinimalLayout.astro +23 -16
  37. package/lib/layouts/parts/ThemeToggle.astro +9 -9
  38. package/lib/link/LinkButton.astro +18 -19
  39. package/lib/link/LinkText.astro +10 -7
  40. package/lib/link/classesTextLink.ts +1 -1
  41. package/lib/list/BlackBulletPoint.astro +1 -1
  42. package/lib/list/BlackBulletPoints.astro +7 -7
  43. package/lib/list/CheckPoint.astro +3 -3
  44. package/lib/list/CheckPoints.astro +3 -3
  45. package/lib/list/NumberedList.astro +1 -1
  46. package/lib/list/Ps.astro +8 -5
  47. package/lib/list/TextOrLink.astro +3 -9
  48. package/lib/md/MarkdownDiv.astro +18 -0
  49. package/lib/modal/Modal.astro +4 -4
  50. package/lib/modal/ModalButton.astro +24 -11
  51. package/lib/page/PageCentered.astro +5 -3
  52. package/lib/page/PageCenteredCard.astro +7 -5
  53. package/lib/page/classesPageCentered.ts +1 -1
  54. package/lib/popover/Popover1.astro +4 -4
  55. package/lib/select/Select.astro +14 -10
  56. package/lib/table/Table.astro +2 -2
  57. package/lib/table/TableD.astro +2 -2
  58. package/lib/table/TableM.astro +2 -2
  59. package/lib/table/TableMEntry.astro +2 -2
  60. package/lib/table/tableVisibilityClasses.ts +3 -3
  61. package/lib/utils/HasId.ts +3 -0
  62. package/lib/utils/HasSubtitle.ts +4 -0
  63. package/lib/utils/HasTitle.ts +4 -0
  64. package/lib/utils/MayHaveButtonVariant.ts +5 -0
  65. package/lib/utils/MayHaveClass.ts +3 -0
  66. package/lib/utils/MayHaveIcon.ts +4 -0
  67. package/lib/utils/MayHaveId.ts +3 -0
  68. package/lib/utils/MayHaveInnerClass.ts +3 -0
  69. package/lib/utils/MayHaveSubtitle.ts +4 -0
  70. package/lib/utils/MayHaveTitle.ts +4 -0
  71. package/package.json +13 -12
  72. package/lib/icon/Icon1.astro +0 -21
  73. package/lib/layouts/MarkdownWrapper.astro +0 -17
  74. package/lib/utils/bun/BunCmd.ts +0 -7
  75. package/lib/utils/bun/cryAndTryAgainLater.ts +0 -6
  76. package/lib/utils/bun/logBunCmd.ts +0 -1
  77. package/lib/utils/bun/runCmdAsync.ts +0 -44
  78. package/lib/utils/bun/runCmdLocally.ts +0 -13
  79. package/lib/utils/obj/objectKeys.ts +0 -21
  80. package/lib/utils/ran/generateId12.ts +0 -7
  81. package/lib/utils/ran/generateId3.ts +0 -7
  82. package/lib/utils/ran/generateId4.ts +0 -7
  83. package/lib/utils/ran/generateId5.ts +0 -7
  84. package/lib/utils/ran/generateId6.ts +0 -7
  85. package/lib/utils/ran/generateId7.ts +0 -7
  86. package/lib/utils/ran/generateReadableId.ts +0 -35
  87. package/lib/utils/ran/urlAlphabet32.ts +0 -8
  88. /package/lib/{layouts/parts → md}/markdown.css +0 -0
  89. /package/lib/utils/{ui/classArr.ts → classArr.ts} +0 -0
  90. /package/lib/utils/{ui/classMerge.ts → classMerge.ts} +0 -0
  91. /package/lib/utils/{ui/isDevEnv.ts → isDevEnv.ts} +0 -0
  92. /package/lib/utils/{ui/tailwindBreakpoint.ts → tailwindBreakpoint.ts} +0 -0
@@ -1,10 +1,9 @@
1
1
  ---
2
- import { generateId5 } from "~/utils/ran/generateId5"
3
- import type { ButtonSize, ButtonVariant } from "~/button/buttonCva"
2
+ import type { ButtonSize, ButtonVariant } from "~ui/button/buttonCva"
4
3
  import Modal from "./Modal.astro"
5
- import { classesTextGray } from "~/text/classesTextGray"
6
- import { classArr } from "~/utils/ui/classArr"
7
- import Button from "~/button/Button.astro"
4
+ import { classesTextGray } from "~ui/text/classesTextGray"
5
+ import { classArr } from "~ui/utils/classArr"
6
+ import Button from "~ui/button/Button.astro"
8
7
 
9
8
  interface Props {
10
9
  button: {
@@ -22,11 +21,25 @@ interface Props {
22
21
  class?: string
23
22
  classContentArea?: string
24
23
  }
25
- const props = Astro.props
26
- const id = props.id ?? `modal-id-${generateId5()}`
27
- const button = props.button
28
- const title = props.title ?? "Dialog Title"
29
- const classContentArea = props.classContentArea
24
+ const p = Astro.props
25
+
26
+ /**
27
+ * Generates a random alphanumeric string ID
28
+ *
29
+ * Uses Math.random() converted to base-36 to create a string of letters and numbers.
30
+ * The substring(2, 11) removes the "0." prefix and takes 9 characters for a good balance
31
+ * of uniqueness and brevity (approximately 10^36 possible combinations).
32
+ *
33
+ * @returns {string} A 9-character random alphanumeric string
34
+ */
35
+ function generateRandomId(): string {
36
+ return Math.random().toString(36).substring(2, 11)
37
+ }
38
+
39
+ const id = p.id ?? `modal-id-${generateRandomId()}`
40
+ const button = p.button
41
+ const title = p.title ?? "Dialog Title"
42
+ const classContentArea = p.classContentArea
30
43
  ---
31
44
 
32
45
  <Button id={id} {...button} />
@@ -34,7 +47,7 @@ const classContentArea = props.classContentArea
34
47
  triggerId={id}
35
48
  title={title}
36
49
  titleClass={classArr(classesTextGray, "text-xl", "mb-2")}
37
- class={props.class}
50
+ class={p.class}
38
51
  classContentArea={classContentArea}
39
52
  >
40
53
  <slot />
@@ -1,14 +1,16 @@
1
1
  ---
2
- import { classMerge } from "~/utils/ui/classMerge"
2
+ import { classMerge } from "~ui/utils/classMerge"
3
3
  import { classesPageCentered } from "./classesPageCentered"
4
+ import type { HTMLAttributes } from "astro/types"
4
5
 
5
6
  interface Props {
6
- id?:string
7
+ id?: string
7
8
  class?: string
9
+ restProps?: HTMLAttributes<"div">
8
10
  }
9
11
  const p = Astro.props
10
12
  ---
11
13
 
12
- <div id={p.id} class={classMerge(classesPageCentered, p.class)}>
14
+ <div id={p.id} class={classMerge(classesPageCentered, p.class)} {...p.restProps}>
13
15
  <slot />
14
16
  </div>
@@ -1,17 +1,19 @@
1
1
  ---
2
- import { classMerge } from "~/utils/ui/classMerge"
2
+ import type { HTMLAttributes } from "astro/types"
3
+ import { classesCardWrapperPage } from "~ui/card/classesCardWrapper"
4
+ import { classMerge } from "~ui/utils/classMerge"
3
5
  import PageCentered from "./PageCentered.astro"
4
- import { classesCardWrapperPage } from "~/card/classesCardWrapper"
5
6
 
6
7
  interface Props {
7
8
  class?: string
8
9
  classInner?: string
10
+ restProps?: HTMLAttributes<"div">
9
11
  }
10
- const props = Astro.props
12
+ const p = Astro.props
11
13
  ---
12
14
 
13
- <PageCentered class={props.class}>
14
- <div class={classMerge(classesCardWrapperPage, props.classInner)}>
15
+ <PageCentered class={p.class} restProps={p.restProps}>
16
+ <div class={classMerge(classesCardWrapperPage, p.classInner)}>
15
17
  <slot />
16
18
  </div>
17
19
  </PageCentered>
@@ -1,4 +1,4 @@
1
- import { classArr } from "~/utils/ui/classArr"
1
+ import { classArr } from "~ui/utils/classArr"
2
2
 
3
3
  export const classesPageCentered = classArr(
4
4
  "flex flex-col justify-center items-center my-auto", // align center
@@ -1,7 +1,7 @@
1
1
  ---
2
- import Icon1 from "~/icon/Icon1.astro"
3
- import { buttonVariant, type ButtonVariant, buttonCva2 } from "~/button/buttonCva"
4
- import { classArr } from "~/utils/ui/classArr"
2
+ import Icon from "~ui/icon/Icon.astro"
3
+ import { buttonVariant, type ButtonVariant, buttonCva2 } from "~ui/button/buttonCva"
4
+ import { classArr } from "~ui/utils/classArr"
5
5
  import { setupPopoverListeners } from "./setupPopoverListeners"
6
6
 
7
7
  interface Props {
@@ -23,7 +23,7 @@ const summaryClasses = buttonCva2(variant, null, "flex flex-wrap gap-2 text-xl f
23
23
  )}
24
24
  >
25
25
  <summary class={summaryClasses}>
26
- <Icon1 path={icon} />
26
+ <Icon path={icon} />
27
27
  {title}
28
28
  </summary>
29
29
  <div
@@ -1,18 +1,21 @@
1
1
  ---
2
- import { classArr } from "~/utils/ui/classArr"
2
+ import type { HTMLAttributes } from "astro/types"
3
+ import { classArr } from "~ui/utils/classArr"
4
+ import type { MayHaveClass } from "~ui/utils/MayHaveClass"
5
+ import type { MayHaveId } from "~ui/utils/MayHaveId"
3
6
 
4
7
  type ValueDisplayFn = (value: string) => string
5
8
 
6
- type NativeSingleSelectProps = {
9
+ export interface Props extends MayHaveId, MayHaveClass {
7
10
  initialValue: string
8
11
  options: string[]
9
12
  optionClass?: string
10
13
  valueDisplay?: ValueDisplayFn
11
14
  id?: string
12
15
  class?: string
16
+ restProps?: HTMLAttributes<"select">
13
17
  }
14
-
15
- const props = Astro.props as NativeSingleSelectProps
18
+ const p = Astro.props
16
19
 
17
20
  const getDisplayValue = (itemValue: string, valueDisplay?: ValueDisplayFn) => {
18
21
  if (!valueDisplay) return itemValue
@@ -23,7 +26,7 @@ const getDisplayValue = (itemValue: string, valueDisplay?: ValueDisplayFn) => {
23
26
  ---
24
27
 
25
28
  <select
26
- id={props.id}
29
+ id={p.id}
27
30
  class={classArr(
28
31
  "block w-full p-2.5",
29
32
  "text-gray-900 dark:text-white text-sm",
@@ -31,14 +34,15 @@ const getDisplayValue = (itemValue: string, valueDisplay?: ValueDisplayFn) => {
31
34
  "bg-gray-50 dark:bg-gray-700",
32
35
  "rounded-lg border border-gray-300 dark:border-gray-600",
33
36
  "focus:ring-blue-500 focus:border-blue-500 dark:focus:border-blue-500 dark:focus:ring-blue-500",
34
- props.class,
37
+ p.class,
35
38
  )}
36
- value={props.initialValue}
39
+ value={p.initialValue}
40
+ {...p.restProps}
37
41
  >
38
42
  {
39
- props.options.map((option: string) => (
40
- <option value={option} class={props.optionClass}>
41
- {getDisplayValue(option, props.valueDisplay)}
43
+ p.options.map((option: string) => (
44
+ <option value={option} class={p.optionClass} selected={option === p.initialValue}>
45
+ {getDisplayValue(option, p.valueDisplay)}
42
46
  </option>
43
47
  ))
44
48
  }
@@ -2,8 +2,8 @@
2
2
  import type { DesktopTableClassses } from "./DesktopTableClassses"
3
3
  import type { MobileTableClassses } from "./MobileTableClassses"
4
4
  import { tableVisibilityClasses } from "./tableVisibilityClasses"
5
- import { classMerge } from "~/utils/ui/classMerge"
6
- import { type TailwindBreakpoint, tailwindBreakpoint } from "~/utils/ui/tailwindBreakpoint"
5
+ import { classMerge } from "~ui/utils/classMerge"
6
+ import { type TailwindBreakpoint, tailwindBreakpoint } from "~ui/utils/tailwindBreakpoint"
7
7
  import type { TableColumnDef } from "./TableColumnDef"
8
8
  import TableD from "./TableD.astro"
9
9
  import TableM from "./TableM.astro"
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  import { type DesktopTableClassses } from "./DesktopTableClassses"
3
3
  import { sharedTableRowClasses } from "./sharedTableRowClasses"
4
- // import { t4table } from "~/ui_tables/table3/t4table"
5
- import { classMerge } from "~/utils/ui/classMerge"
4
+ // import { t4table } from "~ui/ui_tables/table3/t4table"
5
+ import { classMerge } from "~ui/utils/classMerge"
6
6
  import { type TableColumnDef } from "./TableColumnDef"
7
7
 
8
8
  interface Props {
@@ -1,8 +1,8 @@
1
1
  ---
2
- import { classMerge } from "~/utils/ui/classMerge"
2
+ import { classMerge } from "~ui/utils/classMerge"
3
3
  import { type TableColumnDef } from "./TableColumnDef"
4
4
  import TableMEntry from "./TableMEntry.astro"
5
- import type { MobileTableClassses } from "~/table/MobileTableClassses"
5
+ import type { MobileTableClassses } from "~ui/table/MobileTableClassses"
6
6
 
7
7
  interface Props {
8
8
  rows: string[]
@@ -1,7 +1,7 @@
1
1
  ---
2
- import { classMerge } from "~/utils/ui/classMerge"
2
+ import { classMerge } from "~ui/utils/classMerge"
3
3
  import { type TableColumnDef } from "./TableColumnDef"
4
- import type { MobileTableClassses } from "~/table/MobileTableClassses"
4
+ import type { MobileTableClassses } from "~ui/table/MobileTableClassses"
5
5
 
6
6
  interface Props {
7
7
  row: string
@@ -1,6 +1,6 @@
1
- import { classMerge } from "~/utils/ui/classMerge"
2
- import type { TailwindBreakpoint } from "~/utils/ui/tailwindBreakpoint"
3
- import { tailwindBreakpoint } from "~/utils/ui/tailwindBreakpoint"
1
+ import { classMerge } from "~ui/utils/classMerge"
2
+ import type { TailwindBreakpoint } from "~ui/utils/tailwindBreakpoint"
3
+ import { tailwindBreakpoint } from "~ui/utils/tailwindBreakpoint"
4
4
 
5
5
  function tableDesktopclass(b: TailwindBreakpoint) {
6
6
  const tb = tailwindBreakpoint
@@ -0,0 +1,3 @@
1
+ export interface HasId {
2
+ id: string
3
+ }
@@ -0,0 +1,4 @@
1
+ export interface HasSubtitle {
2
+ subtitle: string
3
+ subtitleClass?: string
4
+ }
@@ -0,0 +1,4 @@
1
+ export interface HasTitle {
2
+ title: string
3
+ titleClass?: string
4
+ }
@@ -0,0 +1,5 @@
1
+ import type { ButtonVariant } from "~ui/button/buttonCva"
2
+
3
+ export interface MayHaveButtonVariant {
4
+ variant?: ButtonVariant
5
+ }
@@ -0,0 +1,3 @@
1
+ export interface MayHaveClass {
2
+ class?: string
3
+ }
@@ -0,0 +1,4 @@
1
+ export interface MayHaveIcon {
2
+ icon?: string
3
+ iconClass?: string
4
+ }
@@ -0,0 +1,3 @@
1
+ export interface MayHaveId {
2
+ id?: string
3
+ }
@@ -0,0 +1,3 @@
1
+ export interface MayHaveInnerClass {
2
+ innerClass?: string
3
+ }
@@ -0,0 +1,4 @@
1
+ export interface MayHaveSubtitle {
2
+ subtitle?: string
3
+ subtitleClass?: string
4
+ }
@@ -0,0 +1,4 @@
1
+ export interface MayHaveTitle {
2
+ title?: string
3
+ titleClass?: string
4
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptive-sm/astro-ui",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "scripts": {
5
5
  "astro": "astro",
6
6
  "dev": "nice -5 astro dev",
@@ -10,7 +10,7 @@
10
10
  "upload": "bun run wrangler pages deploy ./dist --project-name=adaptive-astro-ui --commit-dirty",
11
11
  "tag": "git branch -f deployed",
12
12
  "release": "bash ./ops/release.sh",
13
- "generateDemoList": "bun run ./lib/generate_demo_list/generateDemoList.ts",
13
+ "generateDemoList": "bun run ./src/demos/generateDemoList.cli.ts",
14
14
  "generateImageList": "bun run ./src/pages/images/generateImageList.cli.ts",
15
15
  "generateAiRulesLib": "bash ./lib/generate_ai_rules/generate_agent_rules_1_lib.bash",
16
16
  "update": "nice -15 bun x npm-check-updates -u && bun i",
@@ -19,24 +19,25 @@
19
19
  "reset": "rm -rf ./node_modules"
20
20
  },
21
21
  "devDependencies": {
22
- "@astrojs/check": "^0.9.4",
23
- "@biomejs/biome": "^2.2.4",
22
+ "@adaptive-sm/utils": "^0.5.0",
23
+ "@astrojs/check": "^0.9.5",
24
+ "@biomejs/biome": "^2.3.6",
24
25
  "@mdi/js": "^7.4.47",
25
- "@tailwindcss/vite": "^4.1.13",
26
+ "@tailwindcss/vite": "^4.1.17",
26
27
  "@types/bun": "latest",
27
- "astro": "^5.13.9",
28
- "dayjs": "^1.11.18",
28
+ "astro": "^5.15.9",
29
+ "dayjs": "^1.11.19",
29
30
  "image-size": "^2.0.2",
30
31
  "prettier": "^3.6.2",
31
32
  "prettier-plugin-astro": "^0.14.1",
32
33
  "rehype-autolink-headings": "^7.1.0",
33
34
  "rehype-slug": "^6.0.0",
34
35
  "remark-toc": "^9.0.0",
35
- "rollup-plugin-visualizer": "^6.0.3",
36
- "tailwind-merge": "^3.3.1",
37
- "tailwindcss": "^4.1.13",
38
- "typescript": "^5.9.2",
39
- "wrangler": "^4.38.0"
36
+ "rollup-plugin-visualizer": "^6.0.5",
37
+ "tailwind-merge": "^3.4.0",
38
+ "tailwindcss": "^4.1.17",
39
+ "typescript": "^5.9.3",
40
+ "wrangler": "^4.49.0"
40
41
  },
41
42
  "prettier": {
42
43
  "semi": false,
@@ -1,21 +0,0 @@
1
- ---
2
- import { classMerge } from "~/utils/ui/classMerge"
3
-
4
- interface Props {
5
- path: string
6
- class?: string
7
- title?: string
8
- ariaHidden?: boolean
9
- }
10
- const props = Astro.props
11
- const ariaHidden = props.ariaHidden ?? !props.title
12
- // TODO: maybe re-add title={title}
13
- ---
14
-
15
- <svg
16
- viewBox={"0 0 24 24"}
17
- aria-hidden={ariaHidden}
18
- class={classMerge("size-6 flex-shrink-0 align-middle dark:fill-white", props.class)}
19
- >
20
- <path d={props.path}></path>
21
- </svg>
@@ -1,17 +0,0 @@
1
- ---
2
- import PageCenteredCard from "~/page/PageCenteredCard.astro"
3
- import { classMerge } from "~/utils/ui/classMerge"
4
- import { classArr } from "~/utils/ui/classArr"
5
-
6
- import "./parts/markdown.css"
7
-
8
- interface Props {
9
- class?: string
10
- }
11
-
12
- const p = Astro.props
13
- ---
14
-
15
- <PageCenteredCard class={classMerge("max-w-5xl my-12", p.class)} classInner={classArr("markdown-body", p.class)}>
16
- <slot />
17
- </PageCenteredCard>
@@ -1,7 +0,0 @@
1
- export type BunCmd = {
2
- cmd: string[]
3
- success: boolean
4
- exitCode: number
5
- lines: string[]
6
- ms: number
7
- }
@@ -1,6 +0,0 @@
1
- import process from "node:process"
2
-
3
- export function cryAndTryAgainLater<T>(t: T): T {
4
- process.exit(1)
5
- return t
6
- }
@@ -1 +0,0 @@
1
- export const logBunCmd = true
@@ -1,44 +0,0 @@
1
- import console from "node:console"
2
- import type { BunCmd } from "./BunCmd"
3
- import { logBunCmd } from "./logBunCmd"
4
-
5
- export async function runCmdAsync(cmd: string[]): Promise<BunCmd> {
6
- const startedAt = performance.now()
7
- if (logBunCmd) {
8
- console.log({ cmd })
9
- }
10
- const process = Bun.spawn(cmd, {
11
- stdout: "pipe",
12
- stderr: "pipe",
13
- })
14
- const exitCode = await process.exited
15
- const output = await Bun.readableStreamToText(process.stdout)
16
- const error = await Bun.readableStreamToText(process.stderr)
17
- const outputLines = output.split("\n").filter((s) => s.length > 0)
18
- const errorLines = error.split("\n").filter((s) => s.length > 0)
19
- const lines = [...outputLines, ...errorLines]
20
- const endedAt = performance.now()
21
- const ms = Math.round(endedAt - startedAt)
22
- const r: BunCmd = {
23
- cmd,
24
- success: exitCode === 0,
25
- exitCode,
26
- lines,
27
- ms,
28
- }
29
- if (logBunCmd) {
30
- if (lines.length < 8) {
31
- console.log(r)
32
- } else {
33
- const l: Omit<BunCmd, "lines"> = {
34
- cmd,
35
- success: exitCode === 0,
36
- exitCode,
37
- ms,
38
- }
39
- console.log(l)
40
- console.log(JSON.stringify(lines, null, 2))
41
- }
42
- }
43
- return r
44
- }
@@ -1,13 +0,0 @@
1
- import type { BunCmd } from "./BunCmd"
2
- import { cryAndTryAgainLater } from "./cryAndTryAgainLater"
3
- import { runCmdAsync } from "./runCmdAsync"
4
-
5
- export async function runCmdLocally(cmd: string | string[]): Promise<BunCmd> {
6
- return runCmdAsync(["sh", "-c", Array.isArray(cmd) ? cmd.join(" ") : cmd])
7
- }
8
-
9
- export async function runCmdLocallyAndExitOnError(cmd: string | string[]): Promise<BunCmd> {
10
- const got = await runCmdLocally(cmd)
11
- if (!got.success) return cryAndTryAgainLater(got)
12
- return got
13
- }
@@ -1,21 +0,0 @@
1
- /**
2
- * Like Object.keys, but unsound in exchange for more convenience.
3
- *
4
- * Casts the result of Object.keys to the known keys of an object type,
5
- * even though JavaScript objects may contain additional keys.
6
- *
7
- * Only use this function when you know/control the provenance of the object
8
- * you're iterating, and can verify it contains exactly the keys declared
9
- * to the type system.
10
- *
11
- * Example:
12
- * ```
13
- * const o = {x: "ok", y: 10}
14
- * o["z"] = "UNTRACKED_KEY"
15
- * const safeKeys = Object.keys(o)
16
- * const unsafeKeys = objectKeys(o)
17
- * ```
18
- * => const safeKeys: string[]
19
- * => const unsafeKeys: ("x" | "y")[] // Missing "z"
20
- */
21
- export const objectKeys = Object.keys as <T>(obj: T) => Array<keyof T>
@@ -1,7 +0,0 @@
1
- import { generateReadableId } from "~/utils/ran/generateReadableId"
2
-
3
- const gen = generateReadableId(12)
4
-
5
- export function generateId12(): string {
6
- return gen()
7
- }
@@ -1,7 +0,0 @@
1
- import { generateReadableId } from "~/utils/ran/generateReadableId"
2
-
3
- const gen = generateReadableId(3)
4
-
5
- export function generateId3(): string {
6
- return gen()
7
- }
@@ -1,7 +0,0 @@
1
- import { generateReadableId } from "~/utils/ran/generateReadableId"
2
-
3
- const gen = generateReadableId(4)
4
-
5
- export function generateId4(): string {
6
- return gen()
7
- }
@@ -1,7 +0,0 @@
1
- import { generateReadableId } from "./generateReadableId"
2
-
3
- const gen = generateReadableId(5)
4
-
5
- export function generateId5(): string {
6
- return gen()
7
- }
@@ -1,7 +0,0 @@
1
- import { generateReadableId } from "~/utils/ran/generateReadableId"
2
-
3
- const gen = generateReadableId(6)
4
-
5
- export function generateId6(): string {
6
- return gen()
7
- }
@@ -1,7 +0,0 @@
1
- import { generateReadableId } from "~/utils/ran/generateReadableId"
2
-
3
- const gen = generateReadableId(7)
4
-
5
- export function generateId7(): string {
6
- return gen()
7
- }
@@ -1,35 +0,0 @@
1
- import { urlAlphabet32 } from "./urlAlphabet32"
2
-
3
- /**
4
- * * works in browser
5
- * * completely random, not sequential as a feature
6
- * * 32 chars: url friendly, readable, not disambiguate
7
- * * variable length
8
- * * uses secure crypto/web-crypto/node:crypto api
9
- * * generates in batches of 4 for better perf
10
- * @param len - character amount
11
- */
12
- export function generateReadableId(len: number = 16): () => string {
13
- const arr = new Uint16Array(Math.ceil(len / 4))
14
- return () => {
15
- crypto.getRandomValues(arr)
16
- let r = ""
17
- for (const a of arr) {
18
- const n1 = (a >> 9) % 32
19
- r += urlAlphabet32[n1]!
20
- if (r.length >= len) return r
21
-
22
- const n2 = (a >> 6) % 32
23
- r += urlAlphabet32[n2]!
24
-
25
- if (r.length >= len) return r
26
- const n3 = (a >> 3) % 32
27
- r += urlAlphabet32[n3]!
28
-
29
- if (r.length >= len) return r
30
- const n4 = a % 32
31
- r += urlAlphabet32[n4]!
32
- }
33
- return r
34
- }
35
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * - calculate strength - https://zelark.github.io/nano-id-cc/
3
- * - remove 0, O, i, l for better readability and no disambiguity
4
- * - 32 length = 10 (numbers) - 1 (no zero) + 26 (alphabet) - 3 (i,l,o)
5
- * - ignores casing
6
- * - Crockford's Base32 - https://www.crockford.com/base32.html
7
- */
8
- export const urlAlphabet32 = "123456789abcdefghjkmnpqrstuvwxyz"
File without changes
File without changes
File without changes
File without changes