@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.
- package/CHANGELOG.md +25 -0
- package/README.md +33 -33
- package/bin/hfs.mjs +94 -68
- package/lint/run.mjs +161 -0
- package/package.json +3 -2
- package/report/sonar.mjs +14 -29
- package/runtime/engine/admission.mjs +3 -3
- package/runtime/engine/ledger-db.mjs +2 -2
- package/runtime/engine/machine-db.mjs +90 -9
- package/runtime/engine/migrations/machine/0002-worktrees-no-workflow-kind.sql +13 -0
- package/runtime/engine/migrations/runtime/0005-ended-workflow-views.sql +93 -0
- package/runtime/knowledge/hfs/canon-pins.yaml +32 -13
- package/runtime/knowledge/hfs/peer-integrations.yaml +18 -0
- package/runtime/knowledge/hfs/slots.yaml +193 -128
- package/runtime/knowledge/patterns/fe/folder.yaml +36 -36
- package/runtime/knowledge/sonar-gate.yaml +8 -7
- package/runtime/modules/kernel/failure-codes.yaml +31 -52
- package/runtime/scripts/checks/architecture/backend.mjs +1 -1
- package/runtime/scripts/checks/architecture/config.mjs +31 -11
- package/runtime/scripts/checks/architecture/contracts.mjs +4 -4
- package/runtime/scripts/checks/architecture/fe-slot-allows.mjs +7 -3
- package/runtime/scripts/checks/architecture/framework-pinned.mjs +5 -47
- package/runtime/scripts/checks/architecture/frontend.mjs +6 -4
- package/runtime/scripts/checks/architecture/hfs-graph.mjs +1 -1
- package/runtime/scripts/checks/architecture/hfs.mjs +105 -67
- package/runtime/scripts/checks/architecture/index.mjs +18 -13
- package/runtime/scripts/checks/architecture/next-data.mjs +3 -2
- package/runtime/scripts/checks/architecture/owners.mjs +12 -6
- package/runtime/scripts/checks/architecture/registration.mjs +1 -1
- package/runtime/scripts/checks/architecture/surface.mjs +91 -0
- package/runtime/scripts/checks/architecture/symbols.mjs +13 -2
- package/runtime/scripts/checks/architecture/test-world-files.mjs +83 -45
- package/runtime/scripts/checks/architecture/typescript.mjs +127 -29
- package/runtime/scripts/checks/typescript-programs.mjs +2 -2
- package/runtime/scripts/lib/hfs-check.mjs +160 -209
- package/runtime/scripts/lib/hfs-path-findings.mjs +95 -0
- package/runtime/scripts/lib/hfs-rules/contract.mjs +15 -42
- package/runtime/scripts/lib/hfs-rules/frontend.mjs +37 -36
- package/runtime/scripts/lib/hfs-rules/peer-integrations.mjs +44 -0
- package/runtime/scripts/lib/hfs-rules/pipeline.mjs +12 -13
- package/runtime/scripts/lib/hfs-rules/proof-commands.mjs +11 -8
- package/runtime/scripts/lib/hfs-rules/spec-placement.mjs +1 -3
- package/runtime/scripts/lib/hfs-slots.mjs +244 -61
- package/runtime/scripts/lib/hfs-view.mjs +9 -7
- package/runtime/scripts/lib/language.mjs +11 -1
- package/runtime/scripts/lib/safe-remove.mjs +95 -10
- package/scaffold/app.mjs +179 -0
- package/scaffold/service.mjs +26 -16
- package/sync/cli.mjs +1 -1
- package/sync/hygiene.mjs +11 -8
- package/sync/index.mjs +109 -111
- package/sync/managed.mjs +9 -8
- package/sync/sonar-key.mjs +20 -22
- package/templates/{be → app}/ci-workflows/github/workflows/ci.yml +5 -11
- package/templates/app/gitignore +6 -0
- package/templates/app/hooks/husky/pre-commit +25 -0
- package/templates/app/hooks/husky/pre-push +7 -0
- package/templates/app/package-scripts/package.json +22 -0
- package/templates/{be → app}/quality-config/sonar-project.properties +4 -3
- package/templates/app/skeleton/.editorconfig +15 -0
- package/templates/app/skeleton/.gitattributes +2 -0
- package/templates/app/skeleton/.nvmrc +1 -0
- package/templates/app/skeleton/.starciwork/features/index.yaml +7 -0
- package/templates/app/skeleton/.starciwork/workspace.yaml +9 -0
- package/templates/app/skeleton/README.md +36 -0
- package/templates/app/skeleton/scripts/codegen.mjs +4 -0
- package/templates/{fe → app}/tool-config/prettierignore +4 -1
- package/templates/be/skeleton/.sops.yaml +2 -0
- package/templates/be/skeleton/.starcistacks/application-stacks.yaml +10 -0
- package/templates/be/skeleton/apps/__app__/src/__app__.options.ts +3 -0
- package/templates/be/skeleton/apps/__app__/src/app.module.ts +27 -6
- package/templates/be/skeleton/apps/__app__/src/main.ts +4 -1
- package/templates/be/skeleton/src/features/system-health/transport/http/live.controller.ts +2 -0
- package/templates/be/skeleton/src/modules/domain/identity/admission.policy.ts +11 -0
- package/templates/be/skeleton/src/modules/domain/identity/auth.guard.ts +25 -0
- package/templates/be/skeleton/src/modules/domain/identity/errors/identity.error.ts +16 -0
- package/templates/be/skeleton/src/modules/domain/identity/identity.contracts.ts +11 -0
- package/templates/be/skeleton/src/modules/domain/identity/identity.decorators.ts +8 -0
- package/templates/be/skeleton/src/modules/domain/identity/identity.module-definition.ts +7 -0
- package/templates/be/skeleton/src/modules/domain/identity/identity.module.ts +14 -0
- package/templates/be/skeleton/src/modules/domain/identity/identity.options.ts +2 -0
- package/templates/be/skeleton/src/modules/domain/identity/index.ts +6 -0
- package/templates/be/skeleton/src/modules/domain/identity/messages/identity.messages.ts +11 -0
- package/templates/be/skeleton/src/modules/platform/composition/composition.decorators.ts +8 -1
- package/templates/be/skeleton/src/modules/platform/composition/index.ts +1 -1
- package/templates/be/skeleton/src/modules/platform/config/env-source.config.ts +71 -23
- package/templates/be/skeleton/src/modules/platform/config/errors/config.error.ts +14 -16
- package/templates/be/skeleton/src/modules/platform/config/index.ts +1 -1
- package/templates/be/skeleton/src/modules/platform/config/server.config.ts +2 -12
- package/templates/be/skeleton/src/modules/platform/errors/domain.error.ts +16 -7
- package/templates/be/skeleton/src/modules/platform/errors/errors/errors.error.ts +16 -0
- package/templates/be/skeleton/src/modules/platform/errors/errors.contracts.ts +33 -0
- package/templates/be/skeleton/src/modules/platform/errors/errors.decorators.ts +16 -0
- package/templates/be/skeleton/src/modules/platform/errors/errors.filter.ts +32 -0
- package/templates/be/skeleton/src/modules/platform/errors/errors.log-events.ts +2 -2
- package/templates/be/skeleton/src/modules/platform/errors/errors.module-definition.ts +9 -0
- package/templates/be/skeleton/src/modules/platform/errors/errors.module.ts +19 -0
- package/templates/be/skeleton/src/modules/platform/errors/errors.options.ts +7 -0
- package/templates/be/skeleton/src/modules/platform/errors/errors.service.spec.ts +94 -0
- package/templates/be/skeleton/src/modules/platform/errors/errors.service.ts +47 -0
- package/templates/be/skeleton/src/modules/platform/errors/http-status.policy.ts +13 -0
- package/templates/be/skeleton/src/modules/platform/errors/index.ts +4 -1
- package/templates/be/skeleton/src/modules/platform/errors/messages/errors.messages.ts +11 -0
- package/templates/be/skeleton/src/modules/platform/http-security/errors/http-security.error.ts +19 -0
- package/templates/be/skeleton/src/modules/platform/http-security/execution-request.mapper.ts +5 -0
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.config.ts +16 -0
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.decorators.ts +10 -0
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.module-definition.ts +9 -0
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.module.ts +13 -0
- package/templates/be/skeleton/src/modules/platform/http-security/http-security.options.ts +17 -0
- package/templates/be/skeleton/src/modules/platform/http-security/index.ts +7 -0
- package/templates/be/skeleton/src/modules/platform/http-security/messages/http-security.messages.ts +13 -0
- package/templates/be/skeleton/src/modules/platform/http-security/origin.guard.ts +31 -0
- package/templates/be/skeleton/src/modules/platform/http-security/rate-limit.guard.ts +68 -0
- package/templates/be/skeleton/src/modules/platform/i18n/bundle-message-catalog.service.spec.ts +66 -0
- package/templates/be/skeleton/src/modules/platform/i18n/bundle-message-catalog.service.ts +30 -0
- package/templates/be/skeleton/src/modules/platform/i18n/i18n.contracts.ts +18 -0
- package/templates/be/skeleton/src/modules/platform/i18n/i18n.decorators.ts +23 -0
- package/templates/be/skeleton/src/modules/platform/i18n/i18n.module-definition.ts +9 -0
- package/templates/be/skeleton/src/modules/platform/i18n/i18n.module.ts +24 -0
- package/templates/be/skeleton/src/modules/platform/i18n/i18n.options.ts +7 -0
- package/templates/be/skeleton/src/modules/platform/i18n/i18n.port.ts +13 -0
- package/templates/be/skeleton/src/modules/platform/i18n/index.ts +4 -0
- package/templates/be/skeleton/src/modules/platform/i18n/request-locale.service.spec.ts +45 -0
- package/templates/be/skeleton/src/modules/platform/i18n/request-locale.service.ts +19 -0
- package/templates/be/skeleton/src/modules/platform/logging/index.ts +1 -1
- package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.spec.ts +85 -68
- package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.ts +14 -10
- package/templates/be/skeleton/src/modules/platform/logging/logging.decorators.ts +13 -0
- package/templates/be/skeleton/src/modules/platform/logging/logging.log-events.ts +4 -0
- package/templates/be/skeleton/src/modules/platform/logging/logging.port.ts +0 -1
- package/templates/be/skeleton/src/modules/platform/primitives/index.ts +2 -0
- package/templates/be/skeleton/src/modules/platform/primitives/outcome.contracts.ts +25 -0
- package/templates/be/skeleton/src/modules/platform/primitives/outcome.mapper.ts +24 -0
- package/templates/fe/skeleton/apps/__app__/postcss.config.mjs +7 -0
- package/templates/fe/skeleton/apps/__app__/src/app/[locale]/error.tsx +5 -17
- package/templates/fe/skeleton/apps/__app__/src/app/[locale]/layout.tsx +11 -22
- package/templates/fe/skeleton/apps/__app__/src/app/[locale]/loading.tsx +6 -0
- package/templates/fe/skeleton/apps/__app__/src/app/[locale]/not-found.tsx +3 -12
- package/templates/fe/skeleton/apps/__app__/src/app/[locale]/page.tsx +6 -24
- package/templates/fe/skeleton/apps/__app__/src/app/global-error.tsx +4 -18
- package/templates/fe/skeleton/apps/__app__/src/app/globals.css +5 -0
- package/templates/fe/skeleton/apps/__app__/src/components/composites/FailureScreen/index.tsx +28 -0
- package/templates/fe/skeleton/apps/__app__/src/features/layouts/LocaleShell/index.tsx +35 -0
- package/templates/fe/skeleton/apps/__app__/src/features/pages/ErrorPage/component.tsx +21 -0
- package/templates/fe/skeleton/apps/__app__/src/features/pages/ErrorPage/index.tsx +17 -0
- package/templates/fe/skeleton/apps/__app__/src/features/pages/GlobalErrorPage/component.tsx +26 -0
- package/templates/fe/skeleton/apps/__app__/src/features/pages/GlobalErrorPage/index.tsx +15 -0
- package/templates/fe/skeleton/apps/__app__/src/features/pages/HomePage/component.tsx +25 -0
- package/templates/fe/skeleton/apps/__app__/src/features/pages/HomePage/index.tsx +15 -0
- package/templates/fe/skeleton/apps/__app__/src/features/pages/LoadingPage/component.tsx +27 -0
- package/templates/fe/skeleton/apps/__app__/src/features/pages/LoadingPage/index.tsx +8 -0
- package/templates/fe/skeleton/apps/__app__/src/features/pages/NotFoundPage/component.tsx +32 -0
- package/templates/fe/skeleton/apps/__app__/src/features/pages/NotFoundPage/index.tsx +8 -0
- package/templates/fe/skeleton/apps/__app__/src/modules/config/index.ts +12 -0
- package/templates/fe/skeleton/apps/__app__/src/modules/i18n/index.ts +2 -0
- package/templates/fe/skeleton/apps/__app__/src/modules/i18n/messages/vi.json +6 -0
- package/templates/fe/{skeleton-app → skeleton}/apps/__app__/src/modules/i18n/request.ts +1 -0
- package/templates/fe/skeleton/apps/__app__/src/modules/routes/index.ts +4 -0
- package/templates/fe/{skeleton-app → skeleton}/apps/__app__/src/proxy.ts +1 -1
- package/runtime/scripts/checks/architecture/size-growth.mjs +0 -73
- package/sync/skeleton.mjs +0 -76
- package/templates/be/gitignore +0 -2
- package/templates/be/hooks/husky/pre-commit +0 -13
- package/templates/be/hooks/husky/pre-push +0 -7
- package/templates/be/package-scripts/package.json +0 -22
- package/templates/be/skeleton/scripts/.gitkeep +0 -0
- package/templates/be/skeleton/src/modules/platform/config/config.decorators.ts +0 -9
- package/templates/be/skeleton/src/modules/platform/errors/error.filter.ts +0 -20
- package/templates/be/tool-config/prettierignore +0 -8
- package/templates/fe/ci-workflows/github/workflows/ci.yml +0 -54
- package/templates/fe/gitignore +0 -3
- package/templates/fe/hooks/husky/pre-commit +0 -16
- package/templates/fe/hooks/husky/pre-push +0 -6
- package/templates/fe/package-scripts/package.json +0 -17
- package/templates/fe/parts/api-client.ts +0 -44
- package/templates/fe/parts/api-outcome.ts +0 -7
- package/templates/fe/quality-config/sonar-project.properties +0 -8
- package/templates/fe/skeleton/scripts/.gitkeep +0 -0
- package/templates/fe/skeleton-app/apps/__app__/src/modules/api/client.ts +0 -1
- package/templates/fe/skeleton-app/apps/__app__/src/modules/api/index.ts +0 -3
- package/templates/fe/skeleton-app/apps/__app__/src/modules/api/outcome.ts +0 -1
- package/templates/fe/skeleton-app/apps/__app__/src/modules/i18n/index.ts +0 -4
- package/templates/fe/skeleton-app/apps/__app__/src/modules/i18n/navigation.ts +0 -5
- package/templates/fe/skeleton-shared/apps/__app__/next.config.ts +0 -12
- package/templates/fe/skeleton-shared/apps/__app__/src/modules/api/index.ts +0 -2
- package/templates/fe/skeleton-shared/apps/__app__/src/modules/i18n/index.ts +0 -9
- package/templates/fe/skeleton-shared/apps/__app__/src/modules/i18n/request.ts +0 -5
- package/templates/fe/skeleton-shared/apps/__app__/src/proxy.ts +0 -5
- package/templates/fe/skeleton-shared/packages/__family__-api/package.json +0 -12
- package/templates/fe/skeleton-shared/packages/__family__-api/src/client.ts +0 -1
- package/templates/fe/skeleton-shared/packages/__family__-api/src/index.ts +0 -3
- package/templates/fe/skeleton-shared/packages/__family__-api/src/outcome.ts +0 -1
- package/templates/fe/skeleton-shared/packages/__family__-api/tsconfig.json +0 -5
- package/templates/fe/skeleton-shared/packages/__family__-i18n/package.json +0 -18
- package/templates/fe/skeleton-shared/packages/__family__-i18n/src/app.ts +0 -19
- package/templates/fe/skeleton-shared/packages/__family__-i18n/src/index.ts +0 -2
- package/templates/fe/skeleton-shared/packages/__family__-i18n/src/proxy.ts +0 -12
- package/templates/fe/skeleton-shared/packages/__family__-i18n/src/request.ts +0 -15
- package/templates/fe/skeleton-shared/packages/__family__-i18n/tsconfig.json +0 -5
- package/templates/fe/tool-config/prettierrc +0 -1
- /package/templates/{be → app}/ci-workflows/github/workflows/e2e.yml +0 -0
- /package/templates/{be → app}/starciwork.gitignore +0 -0
- /package/templates/{be → app}/tool-config/prettierrc +0 -0
- /package/templates/fe/{skeleton-app → skeleton}/apps/__app__/next.config.ts +0 -0
- /package/templates/fe/{skeleton-app → skeleton}/apps/__app__/src/modules/i18n/config.ts +0 -0
- /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,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 +0,0 @@
|
|
|
1
|
-
{{> fe/parts/api-outcome.ts}}
|
|
@@ -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,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 +0,0 @@
|
|
|
1
|
-
{{> fe/parts/api-client.ts}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{{> fe/parts/api-outcome.ts}}
|
|
@@ -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,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 +0,0 @@
|
|
|
1
|
-
"@starci/prettier-config"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|