hanzio 2.2.0 → 3.1.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 (116) hide show
  1. package/README.md +133 -7
  2. package/dist/api-wrapper/connection-auth.d.ts +61 -0
  3. package/dist/cli/fields.d.ts +30 -0
  4. package/dist/cli/index.d.ts +122 -0
  5. package/dist/format/index.d.ts +91 -0
  6. package/dist/format/phone.d.ts +19 -0
  7. package/dist/http/index.d.ts +14 -0
  8. package/dist/i18n/catalog.d.ts +47 -0
  9. package/dist/i18n/check.d.ts +45 -0
  10. package/dist/i18n/cli.d.ts +2 -0
  11. package/dist/i18n/content-rules.d.ts +55 -0
  12. package/dist/i18n/i18next.d.ts +39 -0
  13. package/dist/i18n/index.d.ts +16 -1
  14. package/dist/i18n/locales.d.ts +62 -0
  15. package/dist/i18n/vite.d.ts +16 -0
  16. package/dist/i18n/vue.d.ts +93 -0
  17. package/dist/{index-kj1phgrx.js → index-29mmh343.js} +24 -1
  18. package/dist/{index-zbj9s3s3.js → index-2kz392vw.js} +1 -1
  19. package/dist/index-5n2e326q.js +409 -0
  20. package/dist/{index-hy7kbb99.js → index-5tzqfmnj.js} +1 -1
  21. package/dist/{index-0zvtcbzy.js → index-6f2w90pp.js} +69 -1
  22. package/dist/index-6ragggbs.js +473 -0
  23. package/dist/index-mq2qgc20.js +116 -0
  24. package/dist/index-najbyzpr.js +99 -0
  25. package/dist/index-ww09bm49.js +250 -0
  26. package/dist/iso/countries.d.ts +262 -0
  27. package/dist/iso/currencies.d.ts +165 -0
  28. package/dist/iso/index.d.ts +4 -0
  29. package/dist/iso/languages.d.ts +195 -0
  30. package/dist/iso/phone-language.d.ts +5 -0
  31. package/dist/promise/index.d.ts +31 -0
  32. package/dist/redis/client.d.ts +49 -0
  33. package/dist/redis/concurrency-limit.d.ts +63 -0
  34. package/dist/redis/index.d.ts +3 -0
  35. package/dist/redis/lua-script.d.ts +13 -0
  36. package/dist/secrets/infisical-identity-file.d.ts +12 -0
  37. package/dist/src/api-wrapper/connection-auth.js +82 -0
  38. package/dist/src/api-wrapper/index.js +1 -1
  39. package/dist/src/cli/index.js +10 -0
  40. package/dist/src/format/index.js +79 -2
  41. package/dist/src/format/phone.js +21 -0
  42. package/dist/src/http/index.js +69 -0
  43. package/dist/src/i18n/check.js +15 -0
  44. package/dist/src/i18n/cli.js +71 -0
  45. package/dist/src/i18n/i18next.js +48 -0
  46. package/dist/src/i18n/index.js +16 -34
  47. package/dist/src/i18n/vite.js +25 -0
  48. package/dist/src/i18n/vue.js +51 -0
  49. package/dist/src/index.js +22 -6
  50. package/dist/src/iso/index.js +655 -0
  51. package/dist/src/redis/index.js +577 -0
  52. package/dist/src/secrets/index.js +78 -35
  53. package/dist/src/sitemap/index.js +1 -1
  54. package/dist/src/storage/index.js +8 -117
  55. package/dist/src/testing/index.js +348 -0
  56. package/dist/src/zod/index.js +20 -253
  57. package/dist/string/index.d.ts +21 -0
  58. package/dist/testing/connection-auth-contract.d.ts +43 -0
  59. package/dist/testing/helpers.d.ts +26 -0
  60. package/dist/testing/index.d.ts +5 -0
  61. package/dist/testing/module-mocker.d.ts +30 -0
  62. package/dist/testing/prisma.d.ts +30 -0
  63. package/dist/testing/window.d.ts +18 -0
  64. package/dist/typedswitch/index.d.ts +55 -34
  65. package/dist/zod/index.d.ts +10 -0
  66. package/dist/zod/introspect.d.ts +2 -1
  67. package/package.json +97 -2
  68. package/src/api-wrapper/README.md +57 -2
  69. package/src/api-wrapper/SKILL.md +256 -0
  70. package/src/api-wrapper/connection-auth.ts +142 -0
  71. package/src/cli/README.md +220 -0
  72. package/src/cli/fields.ts +213 -0
  73. package/src/cli/index.ts +532 -0
  74. package/src/format/README.md +82 -2
  75. package/src/format/index.ts +148 -0
  76. package/src/format/phone.ts +43 -0
  77. package/src/http/README.md +25 -0
  78. package/src/http/index.ts +94 -0
  79. package/src/i18n/README.md +206 -3
  80. package/src/i18n/catalog.ts +139 -0
  81. package/src/i18n/check.ts +376 -0
  82. package/src/i18n/cli.ts +90 -0
  83. package/src/i18n/content-rules.ts +179 -0
  84. package/src/i18n/i18next.ts +89 -0
  85. package/src/i18n/index.ts +34 -0
  86. package/src/i18n/locales.ts +135 -0
  87. package/src/i18n/vite.ts +40 -0
  88. package/src/i18n/vue.ts +82 -0
  89. package/src/index.ts +1 -1
  90. package/src/iso/README.md +44 -0
  91. package/src/iso/countries.ts +272 -0
  92. package/src/iso/currencies.ts +172 -0
  93. package/src/iso/index.ts +8 -0
  94. package/src/iso/languages.ts +208 -0
  95. package/src/iso/phone-language.ts +46 -0
  96. package/src/promise/index.ts +100 -0
  97. package/src/redis/README.md +112 -0
  98. package/src/redis/client.ts +239 -0
  99. package/src/redis/concurrency-limit.ts +591 -0
  100. package/src/redis/index.ts +15 -0
  101. package/src/redis/lua-script.ts +43 -0
  102. package/src/secrets/README.md +5 -1
  103. package/src/secrets/infisical-identity-file.ts +69 -0
  104. package/src/secrets/infisical.ts +18 -3
  105. package/src/string/index.ts +59 -0
  106. package/src/testing/README.md +119 -0
  107. package/src/testing/connection-auth-contract.ts +303 -0
  108. package/src/testing/helpers.ts +41 -0
  109. package/src/testing/index.ts +12 -0
  110. package/src/testing/module-mocker.ts +50 -0
  111. package/src/testing/prisma.ts +78 -0
  112. package/src/testing/window.ts +119 -0
  113. package/src/typedswitch/README.md +55 -39
  114. package/src/typedswitch/index.ts +97 -83
  115. package/src/zod/index.ts +20 -0
  116. package/src/zod/introspect.ts +1 -1
@@ -0,0 +1,69 @@
1
+ // src/http/index.ts
2
+ var SSE_KEEPALIVE_INTERVAL_MS = 15000;
3
+ var SSE_KEEPALIVE_COMMENT = new TextEncoder().encode(`:
4
+
5
+ `);
6
+ function defaultClearTimeout(id) {
7
+ clearTimeout(id);
8
+ }
9
+ function createSseKeepAliveTransform(intervalMs = SSE_KEEPALIVE_INTERVAL_MS, timers = { setTimeout, clearTimeout: defaultClearTimeout }) {
10
+ let timer;
11
+ let closed = false;
12
+ let enqueueKeepAlive;
13
+ const clear = () => {
14
+ if (timer === undefined)
15
+ return;
16
+ timers.clearTimeout(timer);
17
+ timer = undefined;
18
+ };
19
+ const arm = () => {
20
+ clear();
21
+ timer = timers.setTimeout(() => {
22
+ enqueueKeepAlive?.();
23
+ }, intervalMs);
24
+ };
25
+ return new TransformStream({
26
+ start(controller) {
27
+ enqueueKeepAlive = () => {
28
+ if (closed)
29
+ return;
30
+ try {
31
+ controller.enqueue(SSE_KEEPALIVE_COMMENT);
32
+ } catch {
33
+ closed = true;
34
+ clear();
35
+ return;
36
+ }
37
+ arm();
38
+ };
39
+ enqueueKeepAlive();
40
+ },
41
+ transform(chunk, controller) {
42
+ if (closed)
43
+ return;
44
+ controller.enqueue(chunk);
45
+ arm();
46
+ },
47
+ flush() {
48
+ closed = true;
49
+ clear();
50
+ }
51
+ }, { highWaterMark: 16 }, { highWaterMark: 16 });
52
+ }
53
+ function withSseKeepAlive(response, intervalMs = SSE_KEEPALIVE_INTERVAL_MS) {
54
+ const headers = new Headers(response.headers);
55
+ headers.set("Cache-Control", "no-cache");
56
+ headers.set("X-Accel-Buffering", "no");
57
+ headers.set("Connection", "keep-alive");
58
+ const body = response.body ? response.body.pipeThrough(createSseKeepAliveTransform(intervalMs)) : response.body;
59
+ return new Response(body, {
60
+ status: response.status,
61
+ statusText: response.statusText,
62
+ headers
63
+ });
64
+ }
65
+ export {
66
+ SSE_KEEPALIVE_COMMENT,
67
+ createSseKeepAliveTransform,
68
+ withSseKeepAlive
69
+ };
@@ -0,0 +1,15 @@
1
+ import {
2
+ parseMessages2,
3
+ generateCatalogTypes2,
4
+ defineI18nConfig2,
5
+ validateCatalogs2,
6
+ writeCatalogTypes2
7
+ } from "../../index-5n2e326q.js";
8
+ import"../../index-najbyzpr.js";
9
+ export {
10
+ defineI18nConfig2 as defineI18nConfig,
11
+ generateCatalogTypes2 as generateCatalogTypes,
12
+ parseMessages2 as parseMessages,
13
+ validateCatalogs2 as validateCatalogs,
14
+ writeCatalogTypes2 as writeCatalogTypes
15
+ };
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ CliError2,
4
+ defineCommand2,
5
+ defineCli2
6
+ } from "../../index-6ragggbs.js";
7
+ import"../../index-najbyzpr.js";
8
+ import {
9
+ validateCatalogs2,
10
+ writeCatalogTypes2
11
+ } from "../../index-5n2e326q.js";
12
+
13
+ // src/i18n/cli.ts
14
+ import { existsSync } from "node:fs";
15
+ import { dirname, resolve } from "node:path";
16
+ import { pathToFileURL } from "node:url";
17
+ import { z } from "zod";
18
+ var CONFIG_NAMES = [
19
+ "i18n.config.ts",
20
+ "i18n.config.mts",
21
+ "i18n.config.js",
22
+ "i18n.config.mjs"
23
+ ];
24
+ async function loadConfig(file) {
25
+ const path = file ? resolve(file) : CONFIG_NAMES.map((name) => resolve(name)).find((path) => existsSync(path));
26
+ if (!path || !existsSync(path))
27
+ throw new CliError2(`No i18n config found: pass --config or add ${CONFIG_NAMES[0]}.`);
28
+ const loaded = await import(pathToFileURL(path).href);
29
+ if (!loaded.default?.catalogs)
30
+ throw new CliError2(`${path} must default-export an i18n config`);
31
+ return { config: loaded.default, root: dirname(path) };
32
+ }
33
+ function failOnIssues(issues, ctx) {
34
+ if (issues.length === 0)
35
+ return;
36
+ for (const issue of issues) {
37
+ const locale = issue.locale ? `/${issue.locale}` : "";
38
+ ctx.stderr.write(`❌ ${issue.catalog}${locale}: ${issue.message}
39
+ `);
40
+ }
41
+ throw new CliError2(`${issues.length} catalog problem(s)`);
42
+ }
43
+ var cli = defineCli2({
44
+ name: "hanzio-i18n",
45
+ globals: z.object({
46
+ config: z.string().optional().describe("Config file (default: i18n.config.*)")
47
+ }),
48
+ context: (globals) => loadConfig(globals.config),
49
+ commands: {
50
+ check: defineCommand2({
51
+ description: "Validate the translation catalogs",
52
+ run: async (_input, ctx) => {
53
+ const { config, root } = ctx.context;
54
+ failOnIssues(await validateCatalogs2(config, { root }), ctx);
55
+ return config.catalogs.map((catalog) => `✅ ${catalog.name}: ${config.locales.length} locale(s) valid`).join(`
56
+ `);
57
+ }
58
+ }),
59
+ generate: defineCommand2({
60
+ description: "Write each catalog's generatedTypes",
61
+ run: (_input, ctx) => {
62
+ const { config, root } = ctx.context;
63
+ const { written, issues } = writeCatalogTypes2(config, { root });
64
+ failOnIssues(issues, ctx);
65
+ return written.map((path) => `Generated ${path}`).join(`
66
+ `) || undefined;
67
+ }
68
+ })
69
+ }
70
+ });
71
+ process.exitCode = await cli.run();
@@ -0,0 +1,48 @@
1
+ import {
2
+ createAsyncStorageItem2
3
+ } from "../../index-mq2qgc20.js";
4
+
5
+ // src/i18n/i18next.ts
6
+ function initI18next(i18n, options) {
7
+ const { locales, deviceLocales, storageKey, storage, ...initOptions } = options;
8
+ const persisted = storageKey && storage ? createAsyncStorageItem2({
9
+ key: storageKey,
10
+ fallback: null,
11
+ storage,
12
+ serialize: (value) => value ?? "",
13
+ deserialize: (raw) => raw
14
+ }) : undefined;
15
+ const ready = (async () => {
16
+ const locale = locales.resolve(await persisted?.get(), ...deviceLocales?.() ?? []);
17
+ await i18n.init({
18
+ fallbackLng: locales.defaultLocale,
19
+ returnNull: false,
20
+ ...initOptions,
21
+ interpolation: {
22
+ escapeValue: false,
23
+ prefix: "{",
24
+ suffix: "}",
25
+ ...initOptions.interpolation
26
+ },
27
+ lng: locale
28
+ });
29
+ })();
30
+ async function setLocale(locale) {
31
+ if (i18n.language !== locale)
32
+ await i18n.changeLanguage(locale);
33
+ await persisted?.set(locale);
34
+ }
35
+ return {
36
+ ready,
37
+ setLocale,
38
+ locale: () => locales.match(i18n.language) ?? locales.defaultLocale,
39
+ async syncLocale(tag) {
40
+ const locale = locales.match(tag);
41
+ if (locale)
42
+ await setLocale(locale);
43
+ }
44
+ };
45
+ }
46
+ export {
47
+ initI18next
48
+ };
@@ -1,36 +1,18 @@
1
- // src/i18n/index.ts
2
- var PLACEHOLDER_PATTERN = /\{(\w+)\}/g;
3
- function extractPlaceholders(template) {
4
- const names = template.matchAll(PLACEHOLDER_PATTERN).map((match) => match[1]);
5
- return [...new Set(names)];
6
- }
7
- function interpolate(template, ...args) {
8
- const params = args[0] ?? {};
9
- return template.replace(PLACEHOLDER_PATTERN, (match, name) => {
10
- const value = Object.hasOwn(params, name) ? params[name] : undefined;
11
- return value == null ? match : String(value);
12
- });
13
- }
14
- function flattenMessages(messages) {
15
- const out = {};
16
- const visit = (node, prefix) => {
17
- for (const [key, value] of Object.entries(node)) {
18
- if (typeof value === "string")
19
- out[prefix + key] = value;
20
- else
21
- visit(value, `${prefix + key}.`);
22
- }
23
- };
24
- visit(messages, "");
25
- return out;
26
- }
27
- function createTranslator(messages) {
28
- const flat = flattenMessages(messages);
29
- return (key, ...args) => interpolate(flat[key] ?? key, ...args);
30
- }
1
+ import {
2
+ defineLocales2,
3
+ createLocaleSelector2,
4
+ extractPlaceholders2,
5
+ interpolate2,
6
+ flattenMessages2,
7
+ createTranslator2,
8
+ typedTranslate2
9
+ } from "../../index-najbyzpr.js";
31
10
  export {
32
- createTranslator,
33
- extractPlaceholders,
34
- flattenMessages,
35
- interpolate
11
+ createLocaleSelector2 as createLocaleSelector,
12
+ createTranslator2 as createTranslator,
13
+ defineLocales2 as defineLocales,
14
+ extractPlaceholders2 as extractPlaceholders,
15
+ flattenMessages2 as flattenMessages,
16
+ interpolate2 as interpolate,
17
+ typedTranslate2 as typedTranslate
36
18
  };
@@ -0,0 +1,25 @@
1
+ // src/i18n/vite.ts
2
+ var INTLIFY_VIRTUAL_PREFIX = "virtual:intlify-i18n-";
3
+ function localeCatalogReloadPlugin(options = {}) {
4
+ const match = options.match ?? /[/\\]locales[/\\][^/\\]+\.json$/;
5
+ return {
6
+ name: "hanzio-locale-catalog-reload",
7
+ apply: "serve",
8
+ hotUpdate({ file }) {
9
+ if (this.environment.name !== "client")
10
+ return;
11
+ if (!match.test(file))
12
+ return;
13
+ const graph = this.environment.moduleGraph;
14
+ for (const [id, module] of graph.idToModuleMap) {
15
+ if (id.startsWith(INTLIFY_VIRTUAL_PREFIX))
16
+ graph.invalidateModule(module);
17
+ }
18
+ this.environment.hot.send({ type: "full-reload" });
19
+ return [];
20
+ }
21
+ };
22
+ }
23
+ export {
24
+ localeCatalogReloadPlugin
25
+ };
@@ -0,0 +1,51 @@
1
+ import {
2
+ createStorageItem2
3
+ } from "../../index-mq2qgc20.js";
4
+ import {
5
+ typedTranslate2
6
+ } from "../../index-najbyzpr.js";
7
+
8
+ // src/i18n/vue.ts
9
+ import { createI18n, useI18n } from "vue-i18n";
10
+ var browser = globalThis;
11
+ function createVueI18n(options) {
12
+ const { locales, storageKey, storage, ...i18nOptions } = options;
13
+ const persisted = storageKey ? createStorageItem2({
14
+ key: storageKey,
15
+ fallback: null,
16
+ storage,
17
+ serialize: (value) => value ?? "",
18
+ deserialize: (raw) => raw
19
+ }) : undefined;
20
+ const initial = locales.resolve(persisted?.get(), browser.navigator?.language);
21
+ const i18n = createI18n({
22
+ fallbackLocale: locales.defaultLocale,
23
+ ...i18nOptions,
24
+ legacy: false,
25
+ locale: initial
26
+ });
27
+ const apply = (locale) => {
28
+ i18n.global.locale.value = locale;
29
+ if (browser.document)
30
+ browser.document.documentElement.lang = locale;
31
+ };
32
+ apply(initial);
33
+ return {
34
+ i18n,
35
+ setLocale(locale) {
36
+ apply(locale);
37
+ persisted?.set(locale);
38
+ },
39
+ useI18n() {
40
+ const composer = useI18n();
41
+ return {
42
+ ...composer,
43
+ locale: composer.locale,
44
+ t: typedTranslate2(composer.t)
45
+ };
46
+ }
47
+ };
48
+ }
49
+ export {
50
+ createVueI18n
51
+ };
package/dist/src/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  sumBy2,
14
14
  sortBy2,
15
15
  range2
16
- } from "../index-hy7kbb99.js";
16
+ } from "../index-5tzqfmnj.js";
17
17
  import {
18
18
  createCache2
19
19
  } from "../index-k9yx6bne.js";
@@ -32,13 +32,14 @@ import {
32
32
  exponentialBackoff2,
33
33
  retry2,
34
34
  pMap2,
35
+ createTaskPool2,
35
36
  startTimer2,
36
37
  timed2,
37
38
  anySignal2,
38
39
  timeoutSignal2,
39
40
  raceAbort2,
40
41
  createLatestGuard2
41
- } from "../index-0zvtcbzy.js";
42
+ } from "../index-6f2w90pp.js";
42
43
  import {
43
44
  InvariantError2,
44
45
  getErrorMessage2,
@@ -70,8 +71,12 @@ import {
70
71
  foldForSearch2,
71
72
  matchesSearch2,
72
73
  initials2,
73
- safeJsonParse2
74
- } from "../index-kj1phgrx.js";
74
+ safeJsonParse2,
75
+ escapeHtml2,
76
+ stripEmoji2,
77
+ fileExtension2,
78
+ toJsonValue2
79
+ } from "../index-29mmh343.js";
75
80
  import {
76
81
  buildQueryString2,
77
82
  replacePathParams2,
@@ -90,8 +95,8 @@ function typedSwitch(value, keyOrCases, casesOrDefault, defaultCase) {
90
95
  let cases;
91
96
  let defaultHandler;
92
97
  let discriminantKey;
93
- if (typeof value === "string") {
94
- key = value;
98
+ if (typeof value !== "object") {
99
+ key = String(value);
95
100
  cases = keyOrCases;
96
101
  defaultHandler = casesOrDefault;
97
102
  } else {
@@ -119,6 +124,11 @@ function typedSwitch(value, keyOrCases, casesOrDefault, defaultCase) {
119
124
  const contextSuffix = discriminantKey ? ` (discriminant key: "${discriminantKey}")` : "";
120
125
  throw new Error(`Unhandled case: ${key}${contextSuffix}.${availableCasesSuffix}`);
121
126
  }
127
+ function typedSwitchGroup(_value, keyOrKeys, keysOrHandler, handler) {
128
+ const keys = handler ? keysOrHandler : keyOrKeys;
129
+ const shared = handler ?? keysOrHandler;
130
+ return Object.fromEntries(keys.map((key) => [String(key), shared]));
131
+ }
122
132
  function assertNever(value, message) {
123
133
  throw new Error(message ?? `Unexpected value: ${String(value)}`);
124
134
  }
@@ -1003,12 +1013,15 @@ export {
1003
1013
  createLatestGuard2 as createLatestGuard,
1004
1014
  createResolveColorsByKeys,
1005
1015
  createStateMachine,
1016
+ createTaskPool2 as createTaskPool,
1006
1017
  debounce,
1007
1018
  ensureLeadingSlash2 as ensureLeadingSlash,
1008
1019
  err2 as err,
1020
+ escapeHtml2 as escapeHtml,
1009
1021
  escapeRegExp2 as escapeRegExp,
1010
1022
  exponentialBackoff2 as exponentialBackoff,
1011
1023
  extractNumber2 as extractNumber,
1024
+ fileExtension2 as fileExtension,
1012
1025
  findArrayDifferenceByKey2 as findArrayDifferenceByKey,
1013
1026
  foldForSearch2 as foldForSearch,
1014
1027
  formatPeriodLabel,
@@ -1078,6 +1091,7 @@ export {
1078
1091
  sortBy2 as sortBy,
1079
1092
  stableStringify2 as stableStringify,
1080
1093
  startTimer2 as startTimer,
1094
+ stripEmoji2 as stripEmoji,
1081
1095
  sumBy2 as sumBy,
1082
1096
  throttle,
1083
1097
  timed2 as timed,
@@ -1085,6 +1099,7 @@ export {
1085
1099
  toArray2 as toArray,
1086
1100
  toError2 as toError,
1087
1101
  toHex,
1102
+ toJsonValue2 as toJsonValue,
1088
1103
  toRgbString,
1089
1104
  trimTrailingSlash2 as trimTrailingSlash,
1090
1105
  truncate2 as truncate,
@@ -1093,6 +1108,7 @@ export {
1093
1108
  typedFromEntries,
1094
1109
  typedKeys,
1095
1110
  typedSwitch,
1111
+ typedSwitchGroup,
1096
1112
  unwrapResult2 as unwrapResult,
1097
1113
  withAlpha,
1098
1114
  withTimeout2 as withTimeout