@starci/hfs 2.0.2 → 4.0.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 (207) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +33 -33
  3. package/bin/hfs.mjs +94 -68
  4. package/lint/run.mjs +161 -0
  5. package/package.json +3 -2
  6. package/report/sonar.mjs +14 -29
  7. package/runtime/engine/admission.mjs +3 -3
  8. package/runtime/engine/ledger-db.mjs +2 -2
  9. package/runtime/engine/machine-db.mjs +90 -9
  10. package/runtime/engine/migrations/machine/0002-worktrees-no-workflow-kind.sql +13 -0
  11. package/runtime/engine/migrations/runtime/0005-ended-workflow-views.sql +93 -0
  12. package/runtime/knowledge/hfs/canon-pins.yaml +32 -13
  13. package/runtime/knowledge/hfs/peer-integrations.yaml +18 -0
  14. package/runtime/knowledge/hfs/slots.yaml +193 -128
  15. package/runtime/knowledge/patterns/fe/folder.yaml +36 -36
  16. package/runtime/knowledge/sonar-gate.yaml +8 -7
  17. package/runtime/modules/kernel/failure-codes.yaml +31 -52
  18. package/runtime/scripts/checks/architecture/backend.mjs +1 -1
  19. package/runtime/scripts/checks/architecture/config.mjs +31 -11
  20. package/runtime/scripts/checks/architecture/contracts.mjs +4 -4
  21. package/runtime/scripts/checks/architecture/fe-slot-allows.mjs +7 -3
  22. package/runtime/scripts/checks/architecture/framework-pinned.mjs +5 -47
  23. package/runtime/scripts/checks/architecture/frontend.mjs +6 -4
  24. package/runtime/scripts/checks/architecture/hfs-graph.mjs +1 -1
  25. package/runtime/scripts/checks/architecture/hfs.mjs +105 -67
  26. package/runtime/scripts/checks/architecture/index.mjs +18 -13
  27. package/runtime/scripts/checks/architecture/next-data.mjs +3 -2
  28. package/runtime/scripts/checks/architecture/owners.mjs +12 -6
  29. package/runtime/scripts/checks/architecture/registration.mjs +1 -1
  30. package/runtime/scripts/checks/architecture/surface.mjs +91 -0
  31. package/runtime/scripts/checks/architecture/symbols.mjs +13 -2
  32. package/runtime/scripts/checks/architecture/test-world-files.mjs +83 -45
  33. package/runtime/scripts/checks/architecture/typescript.mjs +127 -29
  34. package/runtime/scripts/checks/typescript-programs.mjs +2 -2
  35. package/runtime/scripts/lib/hfs-check.mjs +160 -209
  36. package/runtime/scripts/lib/hfs-path-findings.mjs +95 -0
  37. package/runtime/scripts/lib/hfs-rules/contract.mjs +15 -42
  38. package/runtime/scripts/lib/hfs-rules/frontend.mjs +37 -36
  39. package/runtime/scripts/lib/hfs-rules/peer-integrations.mjs +44 -0
  40. package/runtime/scripts/lib/hfs-rules/pipeline.mjs +12 -13
  41. package/runtime/scripts/lib/hfs-rules/proof-commands.mjs +11 -8
  42. package/runtime/scripts/lib/hfs-rules/spec-placement.mjs +1 -3
  43. package/runtime/scripts/lib/hfs-slots.mjs +244 -61
  44. package/runtime/scripts/lib/hfs-view.mjs +9 -7
  45. package/runtime/scripts/lib/language.mjs +11 -1
  46. package/runtime/scripts/lib/safe-remove.mjs +95 -10
  47. package/scaffold/app.mjs +179 -0
  48. package/scaffold/service.mjs +26 -16
  49. package/sync/cli.mjs +1 -1
  50. package/sync/hygiene.mjs +11 -8
  51. package/sync/index.mjs +109 -111
  52. package/sync/managed.mjs +9 -8
  53. package/sync/sonar-key.mjs +20 -22
  54. package/templates/{be → app}/ci-workflows/github/workflows/ci.yml +5 -11
  55. package/templates/app/gitignore +6 -0
  56. package/templates/app/hooks/husky/pre-commit +25 -0
  57. package/templates/app/hooks/husky/pre-push +7 -0
  58. package/templates/app/package-scripts/package.json +22 -0
  59. package/templates/{be → app}/quality-config/sonar-project.properties +4 -3
  60. package/templates/app/skeleton/.editorconfig +15 -0
  61. package/templates/app/skeleton/.gitattributes +2 -0
  62. package/templates/app/skeleton/.nvmrc +1 -0
  63. package/templates/app/skeleton/.starciwork/features/index.yaml +7 -0
  64. package/templates/app/skeleton/.starciwork/workspace.yaml +9 -0
  65. package/templates/app/skeleton/README.md +36 -0
  66. package/templates/app/skeleton/scripts/codegen.mjs +4 -0
  67. package/templates/{fe → app}/tool-config/prettierignore +4 -1
  68. package/templates/be/skeleton/.sops.yaml +2 -0
  69. package/templates/be/skeleton/.starcistacks/application-stacks.yaml +10 -0
  70. package/templates/be/skeleton/apps/__app__/src/__app__.options.ts +3 -0
  71. package/templates/be/skeleton/apps/__app__/src/app.module.ts +27 -6
  72. package/templates/be/skeleton/apps/__app__/src/main.ts +4 -1
  73. package/templates/be/skeleton/src/features/system-health/transport/http/live.controller.ts +2 -0
  74. package/templates/be/skeleton/src/modules/domain/identity/admission.policy.ts +11 -0
  75. package/templates/be/skeleton/src/modules/domain/identity/auth.guard.ts +25 -0
  76. package/templates/be/skeleton/src/modules/domain/identity/errors/identity.error.ts +16 -0
  77. package/templates/be/skeleton/src/modules/domain/identity/identity.contracts.ts +11 -0
  78. package/templates/be/skeleton/src/modules/domain/identity/identity.decorators.ts +8 -0
  79. package/templates/be/skeleton/src/modules/domain/identity/identity.module-definition.ts +7 -0
  80. package/templates/be/skeleton/src/modules/domain/identity/identity.module.ts +14 -0
  81. package/templates/be/skeleton/src/modules/domain/identity/identity.options.ts +2 -0
  82. package/templates/be/skeleton/src/modules/domain/identity/index.ts +6 -0
  83. package/templates/be/skeleton/src/modules/domain/identity/messages/identity.messages.ts +11 -0
  84. package/templates/be/skeleton/src/modules/platform/composition/composition.decorators.ts +8 -1
  85. package/templates/be/skeleton/src/modules/platform/composition/index.ts +1 -1
  86. package/templates/be/skeleton/src/modules/platform/config/env-source.config.ts +71 -23
  87. package/templates/be/skeleton/src/modules/platform/config/errors/config.error.ts +14 -16
  88. package/templates/be/skeleton/src/modules/platform/config/index.ts +1 -1
  89. package/templates/be/skeleton/src/modules/platform/config/server.config.ts +2 -12
  90. package/templates/be/skeleton/src/modules/platform/errors/domain.error.ts +16 -7
  91. package/templates/be/skeleton/src/modules/platform/errors/errors/errors.error.ts +16 -0
  92. package/templates/be/skeleton/src/modules/platform/errors/errors.contracts.ts +33 -0
  93. package/templates/be/skeleton/src/modules/platform/errors/errors.decorators.ts +16 -0
  94. package/templates/be/skeleton/src/modules/platform/errors/errors.filter.ts +32 -0
  95. package/templates/be/skeleton/src/modules/platform/errors/errors.log-events.ts +2 -2
  96. package/templates/be/skeleton/src/modules/platform/errors/errors.module-definition.ts +9 -0
  97. package/templates/be/skeleton/src/modules/platform/errors/errors.module.ts +19 -0
  98. package/templates/be/skeleton/src/modules/platform/errors/errors.options.ts +7 -0
  99. package/templates/be/skeleton/src/modules/platform/errors/errors.service.spec.ts +94 -0
  100. package/templates/be/skeleton/src/modules/platform/errors/errors.service.ts +47 -0
  101. package/templates/be/skeleton/src/modules/platform/errors/http-status.policy.ts +13 -0
  102. package/templates/be/skeleton/src/modules/platform/errors/index.ts +4 -1
  103. package/templates/be/skeleton/src/modules/platform/errors/messages/errors.messages.ts +11 -0
  104. package/templates/be/skeleton/src/modules/platform/http-security/errors/http-security.error.ts +19 -0
  105. package/templates/be/skeleton/src/modules/platform/http-security/execution-request.mapper.ts +5 -0
  106. package/templates/be/skeleton/src/modules/platform/http-security/http-security.config.ts +16 -0
  107. package/templates/be/skeleton/src/modules/platform/http-security/http-security.decorators.ts +10 -0
  108. package/templates/be/skeleton/src/modules/platform/http-security/http-security.module-definition.ts +9 -0
  109. package/templates/be/skeleton/src/modules/platform/http-security/http-security.module.ts +13 -0
  110. package/templates/be/skeleton/src/modules/platform/http-security/http-security.options.ts +17 -0
  111. package/templates/be/skeleton/src/modules/platform/http-security/index.ts +7 -0
  112. package/templates/be/skeleton/src/modules/platform/http-security/messages/http-security.messages.ts +13 -0
  113. package/templates/be/skeleton/src/modules/platform/http-security/origin.guard.ts +31 -0
  114. package/templates/be/skeleton/src/modules/platform/http-security/rate-limit.guard.ts +68 -0
  115. package/templates/be/skeleton/src/modules/platform/i18n/bundle-message-catalog.service.spec.ts +66 -0
  116. package/templates/be/skeleton/src/modules/platform/i18n/bundle-message-catalog.service.ts +30 -0
  117. package/templates/be/skeleton/src/modules/platform/i18n/i18n.contracts.ts +18 -0
  118. package/templates/be/skeleton/src/modules/platform/i18n/i18n.decorators.ts +23 -0
  119. package/templates/be/skeleton/src/modules/platform/i18n/i18n.module-definition.ts +9 -0
  120. package/templates/be/skeleton/src/modules/platform/i18n/i18n.module.ts +24 -0
  121. package/templates/be/skeleton/src/modules/platform/i18n/i18n.options.ts +7 -0
  122. package/templates/be/skeleton/src/modules/platform/i18n/i18n.port.ts +13 -0
  123. package/templates/be/skeleton/src/modules/platform/i18n/index.ts +4 -0
  124. package/templates/be/skeleton/src/modules/platform/i18n/request-locale.service.spec.ts +45 -0
  125. package/templates/be/skeleton/src/modules/platform/i18n/request-locale.service.ts +19 -0
  126. package/templates/be/skeleton/src/modules/platform/logging/index.ts +1 -1
  127. package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.spec.ts +85 -68
  128. package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.ts +14 -10
  129. package/templates/be/skeleton/src/modules/platform/logging/logging.decorators.ts +13 -0
  130. package/templates/be/skeleton/src/modules/platform/logging/logging.log-events.ts +4 -0
  131. package/templates/be/skeleton/src/modules/platform/logging/logging.port.ts +0 -1
  132. package/templates/be/skeleton/src/modules/platform/primitives/index.ts +2 -0
  133. package/templates/be/skeleton/src/modules/platform/primitives/outcome.contracts.ts +25 -0
  134. package/templates/be/skeleton/src/modules/platform/primitives/outcome.mapper.ts +24 -0
  135. package/templates/fe/skeleton/apps/__app__/postcss.config.mjs +7 -0
  136. package/templates/fe/skeleton/apps/__app__/src/app/[locale]/error.tsx +5 -17
  137. package/templates/fe/skeleton/apps/__app__/src/app/[locale]/layout.tsx +11 -22
  138. package/templates/fe/skeleton/apps/__app__/src/app/[locale]/loading.tsx +6 -0
  139. package/templates/fe/skeleton/apps/__app__/src/app/[locale]/not-found.tsx +3 -12
  140. package/templates/fe/skeleton/apps/__app__/src/app/[locale]/page.tsx +6 -24
  141. package/templates/fe/skeleton/apps/__app__/src/app/global-error.tsx +4 -18
  142. package/templates/fe/skeleton/apps/__app__/src/app/globals.css +5 -0
  143. package/templates/fe/skeleton/apps/__app__/src/components/composites/FailureScreen/index.tsx +28 -0
  144. package/templates/fe/skeleton/apps/__app__/src/features/layouts/LocaleShell/index.tsx +35 -0
  145. package/templates/fe/skeleton/apps/__app__/src/features/pages/ErrorPage/component.tsx +21 -0
  146. package/templates/fe/skeleton/apps/__app__/src/features/pages/ErrorPage/index.tsx +17 -0
  147. package/templates/fe/skeleton/apps/__app__/src/features/pages/GlobalErrorPage/component.tsx +26 -0
  148. package/templates/fe/skeleton/apps/__app__/src/features/pages/GlobalErrorPage/index.tsx +15 -0
  149. package/templates/fe/skeleton/apps/__app__/src/features/pages/HomePage/component.tsx +25 -0
  150. package/templates/fe/skeleton/apps/__app__/src/features/pages/HomePage/index.tsx +15 -0
  151. package/templates/fe/skeleton/apps/__app__/src/features/pages/LoadingPage/component.tsx +27 -0
  152. package/templates/fe/skeleton/apps/__app__/src/features/pages/LoadingPage/index.tsx +8 -0
  153. package/templates/fe/skeleton/apps/__app__/src/features/pages/NotFoundPage/component.tsx +32 -0
  154. package/templates/fe/skeleton/apps/__app__/src/features/pages/NotFoundPage/index.tsx +8 -0
  155. package/templates/fe/skeleton/apps/__app__/src/modules/config/index.ts +12 -0
  156. package/templates/fe/skeleton/apps/__app__/src/modules/i18n/index.ts +2 -0
  157. package/templates/fe/skeleton/apps/__app__/src/modules/i18n/messages/vi.json +6 -0
  158. package/templates/fe/{skeleton-app → skeleton}/apps/__app__/src/modules/i18n/request.ts +1 -0
  159. package/templates/fe/skeleton/apps/__app__/src/modules/routes/index.ts +4 -0
  160. package/templates/fe/{skeleton-app → skeleton}/apps/__app__/src/proxy.ts +1 -1
  161. package/runtime/scripts/checks/architecture/size-growth.mjs +0 -73
  162. package/sync/skeleton.mjs +0 -76
  163. package/templates/be/gitignore +0 -2
  164. package/templates/be/hooks/husky/pre-commit +0 -13
  165. package/templates/be/hooks/husky/pre-push +0 -7
  166. package/templates/be/package-scripts/package.json +0 -22
  167. package/templates/be/skeleton/scripts/.gitkeep +0 -0
  168. package/templates/be/skeleton/src/modules/platform/config/config.decorators.ts +0 -9
  169. package/templates/be/skeleton/src/modules/platform/errors/error.filter.ts +0 -20
  170. package/templates/be/tool-config/prettierignore +0 -8
  171. package/templates/fe/ci-workflows/github/workflows/ci.yml +0 -54
  172. package/templates/fe/gitignore +0 -3
  173. package/templates/fe/hooks/husky/pre-commit +0 -16
  174. package/templates/fe/hooks/husky/pre-push +0 -6
  175. package/templates/fe/package-scripts/package.json +0 -17
  176. package/templates/fe/parts/api-client.ts +0 -44
  177. package/templates/fe/parts/api-outcome.ts +0 -7
  178. package/templates/fe/quality-config/sonar-project.properties +0 -8
  179. package/templates/fe/skeleton/scripts/.gitkeep +0 -0
  180. package/templates/fe/skeleton-app/apps/__app__/src/modules/api/client.ts +0 -1
  181. package/templates/fe/skeleton-app/apps/__app__/src/modules/api/index.ts +0 -3
  182. package/templates/fe/skeleton-app/apps/__app__/src/modules/api/outcome.ts +0 -1
  183. package/templates/fe/skeleton-app/apps/__app__/src/modules/i18n/index.ts +0 -4
  184. package/templates/fe/skeleton-app/apps/__app__/src/modules/i18n/navigation.ts +0 -5
  185. package/templates/fe/skeleton-shared/apps/__app__/next.config.ts +0 -12
  186. package/templates/fe/skeleton-shared/apps/__app__/src/modules/api/index.ts +0 -2
  187. package/templates/fe/skeleton-shared/apps/__app__/src/modules/i18n/index.ts +0 -9
  188. package/templates/fe/skeleton-shared/apps/__app__/src/modules/i18n/request.ts +0 -5
  189. package/templates/fe/skeleton-shared/apps/__app__/src/proxy.ts +0 -5
  190. package/templates/fe/skeleton-shared/packages/__family__-api/package.json +0 -12
  191. package/templates/fe/skeleton-shared/packages/__family__-api/src/client.ts +0 -1
  192. package/templates/fe/skeleton-shared/packages/__family__-api/src/index.ts +0 -3
  193. package/templates/fe/skeleton-shared/packages/__family__-api/src/outcome.ts +0 -1
  194. package/templates/fe/skeleton-shared/packages/__family__-api/tsconfig.json +0 -5
  195. package/templates/fe/skeleton-shared/packages/__family__-i18n/package.json +0 -18
  196. package/templates/fe/skeleton-shared/packages/__family__-i18n/src/app.ts +0 -19
  197. package/templates/fe/skeleton-shared/packages/__family__-i18n/src/index.ts +0 -2
  198. package/templates/fe/skeleton-shared/packages/__family__-i18n/src/proxy.ts +0 -12
  199. package/templates/fe/skeleton-shared/packages/__family__-i18n/src/request.ts +0 -15
  200. package/templates/fe/skeleton-shared/packages/__family__-i18n/tsconfig.json +0 -5
  201. package/templates/fe/tool-config/prettierrc +0 -1
  202. /package/templates/{be → app}/ci-workflows/github/workflows/e2e.yml +0 -0
  203. /package/templates/{be → app}/starciwork.gitignore +0 -0
  204. /package/templates/{be → app}/tool-config/prettierrc +0 -0
  205. /package/templates/fe/{skeleton-app → skeleton}/apps/__app__/next.config.ts +0 -0
  206. /package/templates/fe/{skeleton-app → skeleton}/apps/__app__/src/modules/i18n/config.ts +0 -0
  207. /package/templates/fe/{skeleton-app → skeleton}/apps/__app__/src/modules/i18n/routing.ts +0 -0
@@ -1,16 +0,0 @@
1
- {{header}}
2
- # Commit gate: the secrets guard, then types, lint and format of the staged files.
3
- npx hfs work-hygiene
4
- npm run typecheck
5
- sources=$(git diff --cached --name-only --diff-filter=ACMR -- '*.ts' '*.tsx' '*.mts' '*.cts' '*.js' '*.jsx' '*.mjs' '*.cjs' || true)
6
- if [ -n "$sources" ]; then
7
- npx eslint --max-warnings=0 --no-warn-ignored $sources
8
- fi
9
- styles=$(git diff --cached --name-only --diff-filter=ACMR -- '*.css' || true)
10
- if [ -n "$styles" ]; then
11
- npx stylelint $styles
12
- fi
13
- formatted=$(git diff --cached --name-only --diff-filter=ACMR || true)
14
- if [ -n "$formatted" ]; then
15
- npx prettier --check --ignore-unknown $formatted
16
- fi
@@ -1,6 +0,0 @@
1
- {{header}}
2
- # Push gate: types, lint (eslint over the repository, stylelint over the CSS), format, the architecture check on the owners this push touches.
3
- npm run typecheck
4
- npm run lint:check
5
- npm run format:check
6
- npm run hfs:check -- --fast
@@ -1,17 +0,0 @@
1
- {
2
- "scripts": {
3
- "prepare": "husky",
4
- {{appScripts}}
5
- "codegen": "npm run codegen --workspaces --if-present",
6
- "build": "npm run build --workspaces --if-present",
7
- "typecheck": "npm run typecheck --workspaces --if-present",
8
- "lint": "npm run codegen --silent && eslint . --fix --max-warnings=0 && stylelint \"{{styleGlob}}\" --fix",
9
- "lint:check": "npm run codegen --silent && eslint . --max-warnings=0 && stylelint \"{{styleGlob}}\"",
10
- "lint:report": "eslint . --format json --output-file reports/eslint.json",
11
- "lint:report:css": "stylelint \"{{styleGlob}}\" --formatter json --output-file reports/stylelint.json",
12
- "format": "prettier --write .",
13
- "format:check": "prettier --check .",
14
- "hfs:check": "hfs check",
15
- "hfs:report": "hfs check --sonar reports/hfs.sonar.json"
16
- }
17
- }
@@ -1,44 +0,0 @@
1
- import type { Outcome } from "./outcome"
2
-
3
- /** How long a request waits before it is abandoned and answered `unavailable`. */
4
- const REQUEST_TIMEOUT_MS = 8000
5
-
6
- /** One request of the client: the caller's own signal is joined with the timeout. */
7
- export interface ClientRequest {
8
- readonly url: string
9
- readonly method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE"
10
- readonly body?: unknown
11
- readonly signal?: AbortSignal
12
- }
13
-
14
- /** The status of a response as an Outcome kind; 401 and 403 are `refused`, nothing collapses into `null`. */
15
- const toOutcome = async (response: Response): Promise<Outcome<unknown>> => {
16
- if (response.status === 401 || response.status === 403) return { kind: "refused" }
17
- if (response.status === 404) return { kind: "not-found" }
18
- if (response.status === 400 || response.status === 422) return { kind: "invalid" }
19
- if (!response.ok) return { kind: "unavailable" }
20
- try {
21
- return { kind: "ok", data: (await response.json()) as unknown }
22
- } catch {
23
- return { kind: "unavailable" }
24
- }
25
- }
26
-
27
- /**
28
- * The repository's one fetch. It always carries a timeout signal, never throws, and answers an Outcome; the body is
29
- * `unknown` until a generated wire type narrows it.
30
- */
31
- export const request = async ({ url, method = "GET", body, signal }: ClientRequest): Promise<Outcome<unknown>> => {
32
- const timeout = AbortSignal.timeout(REQUEST_TIMEOUT_MS)
33
- try {
34
- const response = await fetch(url, {
35
- method,
36
- headers: { accept: "application/json", ...(body === undefined ? {} : { "content-type": "application/json" }) },
37
- ...(body === undefined ? {} : { body: JSON.stringify(body) }),
38
- signal: signal === undefined ? timeout : AbortSignal.any([signal, timeout]),
39
- })
40
- return await toOutcome(response)
41
- } catch {
42
- return { kind: "unavailable" }
43
- }
44
- }
@@ -1,7 +0,0 @@
1
- /** The one result every read of the backend returns: a status is a kind, never a thrown error and never `null`. */
2
- export type Outcome<T> =
3
- | { readonly kind: "ok"; readonly data: T }
4
- | { readonly kind: "refused" }
5
- | { readonly kind: "invalid" }
6
- | { readonly kind: "not-found" }
7
- | { readonly kind: "unavailable" }
@@ -1,8 +0,0 @@
1
- {{header}}
2
- sonar.projectKey={{sonarKey}}
3
- sonar.sourceEncoding=UTF-8
4
- sonar.sources={{sonarRoots}}
5
- sonar.exclusions=**/.next/**,**/node_modules/**,**/src/messages/**
6
- sonar.typescript.tsconfigPaths={{tsconfigPaths}}
7
- sonar.externalIssuesReportPaths=reports/hfs.sonar.json,reports/eslint.sonar.json,reports/stylelint.sonar.json
8
- sonar.nodejs.maxspace=8192
File without changes
@@ -1 +0,0 @@
1
- {{> fe/parts/api-client.ts}}
@@ -1,3 +0,0 @@
1
- export { request } from "./client"
2
- export type { ClientRequest } from "./client"
3
- export type { Outcome } from "./outcome"
@@ -1 +0,0 @@
1
- {{> fe/parts/api-outcome.ts}}
@@ -1,4 +0,0 @@
1
- export { DEFAULT_LOCALE, LOCALES } from "./config"
2
- export type { Locale } from "./config"
3
- export { getPathname, Link, redirect, usePathname, useRouter } from "./navigation"
4
- export { routing } from "./routing"
@@ -1,5 +0,0 @@
1
- import { createNavigation } from "next-intl/navigation"
2
- import { routing } from "./routing"
3
-
4
- /** Locale-aware links and navigation; components import these instead of `next/link` and `next/navigation`. */
5
- export const { Link, redirect, usePathname, useRouter, getPathname } = createNavigation(routing)
@@ -1,12 +0,0 @@
1
- import type { NextConfig } from "next"
2
- import createNextIntlPlugin from "next-intl/plugin"
3
-
4
- const withNextIntl = createNextIntlPlugin("./src/modules/i18n/request.ts")
5
-
6
- /** Next config of the {{app}} app: next-intl wired to the request config, Turbopack rooted at the repository, the shared packages compiled from source. */
7
- const nextConfig: NextConfig = {
8
- turbopack: { root: process.cwd() },
9
- transpilePackages: ["@{{family}}/i18n", "@{{family}}/api"],
10
- }
11
-
12
- export default withNextIntl(nextConfig)
@@ -1,2 +0,0 @@
1
- export { request } from "@{{family}}/api"
2
- export type { ClientRequest, Outcome } from "@{{family}}/api"
@@ -1,9 +0,0 @@
1
- import { createAppI18n } from "@{{family}}/i18n"
2
-
3
- /** This app's locales and the next-intl stack (routing, navigation) built from them by the shared i18n package. */
4
- const i18n = createAppI18n({ locales: ["vi"], defaultLocale: "vi" })
5
-
6
- export const { DEFAULT_LOCALE, LOCALES, getPathname, Link, redirect, routing, usePathname, useRouter } = i18n
7
-
8
- /** A served locale. */
9
- export type Locale = (typeof LOCALES)[number]
@@ -1,5 +0,0 @@
1
- import { createRequestConfig } from "@{{family}}/i18n/request"
2
- import { routing } from "./index"
3
-
4
- /** Loads the catalog of the requested locale from this app's `messages/`; the shared package resolves the locale. */
5
- export default createRequestConfig(routing, async (locale) => (await import(`./messages/${locale}.json`)).default)
@@ -1,5 +0,0 @@
1
- import { createProxy } from "@{{family}}/i18n/proxy"
2
- import { routing } from "./modules/i18n"
3
-
4
- /** Negotiates the locale and redirects; the default locale (vi) is served without a prefix. */
5
- export default createProxy(routing)
@@ -1,12 +0,0 @@
1
- {
2
- "name": "@{{family}}/api",
3
- "version": "0.1.0",
4
- "private": true,
5
- "type": "module",
6
- "exports": {
7
- ".": "./src/index.ts"
8
- },
9
- "scripts": {
10
- "typecheck": "tsc --noEmit --pretty false"
11
- }
12
- }
@@ -1 +0,0 @@
1
- {{> fe/parts/api-client.ts}}
@@ -1,3 +0,0 @@
1
- export { request } from "./client"
2
- export type { ClientRequest } from "./client"
3
- export type { Outcome } from "./outcome"
@@ -1 +0,0 @@
1
- {{> fe/parts/api-outcome.ts}}
@@ -1,5 +0,0 @@
1
- {
2
- "extends": "@starci/tsconfig/next.json",
3
- "include": ["src/**/*.ts", "src/**/*.tsx"],
4
- "exclude": ["node_modules"]
5
- }
@@ -1,18 +0,0 @@
1
- {
2
- "name": "@{{family}}/i18n",
3
- "version": "0.1.0",
4
- "private": true,
5
- "type": "module",
6
- "exports": {
7
- ".": "./src/index.ts",
8
- "./proxy": "./src/proxy.ts",
9
- "./request": "./src/request.ts"
10
- },
11
- "scripts": {
12
- "typecheck": "tsc --noEmit --pretty false"
13
- },
14
- "peerDependencies": {
15
- "next": ">=16",
16
- "next-intl": ">=4"
17
- }
18
- }
@@ -1,19 +0,0 @@
1
- import { createNavigation } from "next-intl/navigation"
2
- import { defineRouting } from "next-intl/routing"
3
-
4
- /** The locales an app serves and the one it serves at the unprefixed path. */
5
- export interface AppI18nOptions<Locale extends string> {
6
- readonly locales: readonly [Locale, ...Locale[]]
7
- readonly defaultLocale: Locale
8
- }
9
-
10
- /**
11
- * The next-intl stack of one app, written once for the repository: one routing table (default locale unprefixed) and the
12
- * locale-aware navigation built on it. Components import `Link` and `redirect` from their app's i18n module, never from
13
- * `next/link` or `next/navigation`. The proxy and the request config are the `./proxy` and `./request` entries, so a client
14
- * bundle that imports this one carries no server code.
15
- */
16
- export const createAppI18n = <const Locale extends string>({ locales, defaultLocale }: AppI18nOptions<Locale>) => {
17
- const routing = defineRouting({ locales, defaultLocale, localePrefix: "as-needed" })
18
- return { LOCALES: locales, DEFAULT_LOCALE: defaultLocale, routing, ...createNavigation(routing) }
19
- }
@@ -1,2 +0,0 @@
1
- export { createAppI18n } from "./app"
2
- export type { AppI18nOptions } from "./app"
@@ -1,12 +0,0 @@
1
- import createMiddleware from "next-intl/middleware"
2
- import type { defineRouting } from "next-intl/routing"
3
- import { NextResponse, type NextRequest } from "next/server"
4
-
5
- /** The API, the health probe, framework files and files with an extension are never locale-negotiated. */
6
- const UNNEGOTIATED = /^\/(?:api|health|_next|_vercel)(?:\/|$)|\.[^/]+$/
7
-
8
- /** The proxy of an app: negotiates the locale and redirects, and lets everything that is not a page through untouched. */
9
- export const createProxy = (routing: ReturnType<typeof defineRouting>) => {
10
- const negotiate = createMiddleware(routing)
11
- return (request: NextRequest) => (UNNEGOTIATED.test(request.nextUrl.pathname) ? NextResponse.next() : negotiate(request))
12
- }
@@ -1,15 +0,0 @@
1
- import { hasLocale } from "next-intl"
2
- import type { defineRouting } from "next-intl/routing"
3
- import { getRequestConfig } from "next-intl/server"
4
-
5
- type Routing = ReturnType<typeof defineRouting>
6
-
7
- /** The requested locale when the app serves it, else the default one. */
8
- export const resolveLocale = (routing: Routing, requested: string | undefined): string => (hasLocale(routing.locales, requested) ? requested : routing.defaultLocale)
9
-
10
- /** The request config of an app: the resolved locale and the catalog the app loads for it. */
11
- export const createRequestConfig = (routing: Routing, loadMessages: (locale: string) => Promise<Record<string, unknown>>) =>
12
- getRequestConfig(async ({ requestLocale }) => {
13
- const locale = resolveLocale(routing, await requestLocale)
14
- return { locale, messages: await loadMessages(locale) }
15
- })
@@ -1,5 +0,0 @@
1
- {
2
- "extends": "@starci/tsconfig/next.json",
3
- "include": ["src/**/*.ts", "src/**/*.tsx"],
4
- "exclude": ["node_modules"]
5
- }
@@ -1 +0,0 @@
1
- "@starci/prettier-config"
File without changes
File without changes