@ykdz/template 0.0.33 → 0.0.36
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/dist/application.d.ts +2 -1
- package/dist/application.js +64 -75
- package/dist/main.js +6 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.d.ts +50 -36
- package/node_modules/@ykdz/template-builtin-presets/dist/src/foundation.js +970 -365
- package/node_modules/@ykdz/template-builtin-presets/dist/src/generation-record.d.ts +24 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/generation-record.js +154 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/index.d.ts +2 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/index.js +1 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/rust-bin/definition.d.ts +31 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/rust-bin/definition.js +29 -33
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/development-container.d.ts +1 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/development-container.js +17 -0
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/typescript.d.ts +4 -3
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/typescript.js +9 -5
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.d.ts +1 -1
- package/node_modules/@ykdz/template-builtin-presets/dist/src/shared/vue.js +1 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-cli/definition.d.ts +31 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-cli/definition.js +79 -58
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-lib/definition.d.ts +31 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/ts-lib/definition.js +31 -23
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vike-app/definition.d.ts +22 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vike-app/definition.js +61 -35
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-app/definition.d.ts +26 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-app/definition.js +19 -8
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-hono-app/definition.d.ts +22 -2
- package/node_modules/@ykdz/template-builtin-presets/dist/src/vue-hono-app/definition.js +31 -21
- package/node_modules/@ykdz/template-builtin-presets/package.json +12 -11
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment-diagnostics.yml +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.github/workflows/check-deployment.yml +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/.pnpmfile.mjs +19 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/gitignore +1 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/foundation/tsconfig.packing-hook.json +8 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/shared/devcontainer/github-cli.Dockerfile +9 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/CHANGELOG.md.template +17 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/RELEASING.md +17 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/artifact.ts +1271 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/changelog.ts +283 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/check-artifact.ts +99 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/check-readiness.ts +66 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/cli-command-identity.ts +4 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/handoff.ts +450 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/publish.ts +483 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/readiness.ts +1125 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/release.ts +819 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/release.yml +119 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/root-tsconfig.json +13 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/tsconfig.json +4 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication/turbo.json +6 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/README.md +48 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/assets/CHANGELOG.md.template +17 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/assets/LICENSE-APACHE-2.0.txt +202 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/assets/LICENSE-MIT.txt +21 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/assets/README.md.template +5 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/bridge.ts +3336 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/setup.sh +221 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/cli-command-identity.ts +133 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/cli.ts +4 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/main.ts +5 -4
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/integration/command.test.ts +14 -13
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/test/unit/cli-command-identity.test.ts +76 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/tsconfig.build.json +2 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/src/readiness.ts +1 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/test/global-setup.ts +21 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/tsconfig.json +6 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/vitest.config.ts +7 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db-migrations/drizzle.config.ts +5 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/playwright.config.ts +102 -22
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/test/playwright-teardown.ts +12 -0
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/vite.config.ts +39 -1
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-app/playwright.config.ts +48 -7
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/playwright.config.ts +59 -8
- package/node_modules/@ykdz/template-core/dist/module-graph.d.ts +15 -53
- package/node_modules/@ykdz/template-core/dist/module-graph.js +134 -101
- package/node_modules/@ykdz/template-core/dist/package-contribution.d.ts +13 -1
- package/node_modules/@ykdz/template-core/dist/package-contribution.js +92 -0
- package/node_modules/@ykdz/template-core/dist/pnpm-workspace.yaml +14 -10
- package/node_modules/@ykdz/template-core/dist/preset-definition.d.ts +71 -13
- package/node_modules/@ykdz/template-core/dist/preset-definition.js +16 -1
- package/node_modules/@ykdz/template-core/dist/project-blueprint.d.ts +56 -0
- package/node_modules/@ykdz/template-core/dist/project-blueprint.js +271 -0
- package/node_modules/@ykdz/template-core/dist/project-linking-v2.d.ts +2 -2
- package/node_modules/@ykdz/template-core/dist/project-linking-v2.js +2 -2
- package/node_modules/@ykdz/template-core/dist/project-projection.d.ts +2 -1
- package/node_modules/@ykdz/template-core/dist/project-projection.js +107 -20
- package/node_modules/@ykdz/template-core/dist/renderer.d.ts +0 -2
- package/node_modules/@ykdz/template-core/dist/renderer.js +17 -38
- package/node_modules/@ykdz/template-core/dist/template-boundary-check.d.ts +2 -2
- package/node_modules/@ykdz/template-core/dist/template-boundary-check.js +6 -0
- package/node_modules/@ykdz/template-core/dist/toolchain-resolution.d.ts +2 -0
- package/node_modules/@ykdz/template-core/dist/toolchain-resolution.js +9 -3
- package/package.json +3 -3
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db-migrations/scripts/prepare-database.ts +0 -45
- package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/web/scripts/run-playwright.ts +0 -151
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-app/scripts/run-playwright.ts +0 -62
- package/node_modules/@ykdz/template-builtin-presets/templates/vue-hono-app/web/scripts/run-playwright.ts +0 -103
- package/node_modules/@ykdz/template-core/dist/project-blueprint-v2.d.ts +0 -33
- package/node_modules/@ykdz/template-core/dist/project-blueprint-v2.js +0 -182
package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/publication-setup/setup.sh
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# One-time, local-only setup interface. The generated body is checked Template Source.
|
|
3
|
+
|
|
4
|
+
set -u
|
|
5
|
+
|
|
6
|
+
package_path="{{PUBLIC_CLI_PACKAGE_PATH}}"
|
|
7
|
+
script_dir=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)
|
|
8
|
+
repository_root=$(CDPATH='' cd -- "$script_dir/../.." && pwd)
|
|
9
|
+
mode="run"
|
|
10
|
+
status_requested=false
|
|
11
|
+
json_requested=false
|
|
12
|
+
non_interactive=false
|
|
13
|
+
debug=false
|
|
14
|
+
package_name=""
|
|
15
|
+
command_name=""
|
|
16
|
+
description=""
|
|
17
|
+
license=""
|
|
18
|
+
copyright_holder=""
|
|
19
|
+
repository=""
|
|
20
|
+
|
|
21
|
+
usage() {
|
|
22
|
+
cat <<'USAGE'
|
|
23
|
+
Usage: ./scripts/npm-publication-setup/setup.sh [public-fact options] [--non-interactive] [--debug]
|
|
24
|
+
./scripts/npm-publication-setup/setup.sh --status --json
|
|
25
|
+
./scripts/npm-publication-setup/setup.sh --help
|
|
26
|
+
USAGE
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
diagnostic() {
|
|
30
|
+
local kind=$1 code=$2 observed expected next
|
|
31
|
+
observed=$(sanitize "$3")
|
|
32
|
+
expected=$(sanitize "$4")
|
|
33
|
+
next=$(sanitize "$5")
|
|
34
|
+
printf '%s %s\nObserved: %s\nExpected: %s\nNext action: %s\n' "$kind" "$code" "$observed" "$expected" "$next" >&2
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
fail() { diagnostic "$1" "$2" "$3" "$4" "$5"; exit "$6"; }
|
|
38
|
+
|
|
39
|
+
redact() {
|
|
40
|
+
sed -E 's#(https?://)[^/@[:space:]]+@#\1[REDACTED]@#g; s#(token|password|otp|session|authorization|auth|config)[=:][^[:space:]]+#\1=[REDACTED]#gI; s#(bearer|basic)[[:space:]]+[^[:space:]]+#\1 [REDACTED]#gI'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
sanitize() {
|
|
44
|
+
printf '%s' "$1" | LC_ALL=C tr -d '\000-\037\177-\237' | redact
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
prompt_public_fact() {
|
|
48
|
+
local label=$1 variable=$2
|
|
49
|
+
printf '%s: ' "$label"
|
|
50
|
+
# shellcheck disable=SC2229
|
|
51
|
+
if ! IFS= read -r "$variable"; then
|
|
52
|
+
fail "ACTION REQUIRED" public-fact-required "end of input" "a complete public package fact" "Run with all public flags or enter the remaining facts interactively." 3
|
|
53
|
+
fi
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
require_value() {
|
|
57
|
+
[ "$#" -eq 2 ] || fail ERROR publication-setup-usage "missing flag value" "a value for $1" "Run --help and provide public facts." 2
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
status_json_intent=false
|
|
61
|
+
status_flag_seen=false
|
|
62
|
+
json_flag_seen=false
|
|
63
|
+
for argument in "$@"; do
|
|
64
|
+
[ "$argument" = "--status" ] && status_flag_seen=true
|
|
65
|
+
[ "$argument" = "--json" ] && json_flag_seen=true
|
|
66
|
+
done
|
|
67
|
+
[ "$status_flag_seen" = true ] && [ "$json_flag_seen" = true ] && status_json_intent=true
|
|
68
|
+
|
|
69
|
+
status_usage_json() {
|
|
70
|
+
printf '%s\n' '{"schemaVersion":1,"currentStage":{"id":"check-prerequisites","number":1,"name":"Check prerequisites"},"observations":{"packagePath":null,"packageName":null,"commandName":null,"version":null,"repository":null,"readiness":"unavailable","git":{"workingTree":null,"currentBranch":null,"defaultBranch":null,"headMatchesRemoteDefault":null}},"blockers":[{"code":"publication-setup-usage","observed":"invalid status arguments","expected":"--status --json only","nextAction":"Run ./scripts/npm-publication-setup/setup.sh --status --json."}],"nextAction":{"kind":"run","command":"./scripts/npm-publication-setup/setup.sh"}}'
|
|
71
|
+
exit 2
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
usage_fail() {
|
|
75
|
+
if [ "$status_json_intent" = true ]; then status_usage_json; fi
|
|
76
|
+
fail "$@"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
while [ "$#" -gt 0 ]; do
|
|
80
|
+
case "$1" in
|
|
81
|
+
--help) [ "$#" -eq 1 ] || usage_fail ERROR publication-setup-usage "--help with other arguments" "--help alone" "Run --help by itself." 2; usage; exit 0 ;;
|
|
82
|
+
--status) mode="status"; status_requested=true ;;
|
|
83
|
+
--json) json_requested=true ;;
|
|
84
|
+
--non-interactive) non_interactive=true ;;
|
|
85
|
+
--debug) debug=true ;;
|
|
86
|
+
--package-name|--bin|--description|--license|--copyright-holder|--repository)
|
|
87
|
+
flag=$1; shift; [ "$#" -gt 0 ] || usage_fail ERROR publication-setup-usage "missing value" "a value for $flag" "Run --help and provide public facts." 2
|
|
88
|
+
case "$flag" in
|
|
89
|
+
--package-name) package_name=$1 ;; --bin) command_name=$1 ;; --description) description=$1 ;;
|
|
90
|
+
--license) license=$1 ;; --copyright-holder) copyright_holder=$1 ;; --repository) repository=$1 ;;
|
|
91
|
+
esac ;;
|
|
92
|
+
--yes|--password|--otp|--token|--secret|--session|--release-date|--*)
|
|
93
|
+
usage_fail ERROR publication-setup-usage "$1" "a supported public option" "Run --help; credentials and automatic acceptance are unsupported." 2 ;;
|
|
94
|
+
*) usage_fail ERROR publication-setup-usage "$1" "no positional arguments" "Run --help." 2 ;;
|
|
95
|
+
esac
|
|
96
|
+
shift
|
|
97
|
+
done
|
|
98
|
+
|
|
99
|
+
if [ "$status_requested" != "$json_requested" ]; then
|
|
100
|
+
usage_fail ERROR publication-setup-usage "--status and --json must be paired" "--status --json" "Run --status --json." 2
|
|
101
|
+
fi
|
|
102
|
+
if [ "$json_requested" = true ] && [ "$mode" != "status" ]; then
|
|
103
|
+
usage_fail ERROR publication-setup-usage "--json without --status" "--status --json" "Run --status --json." 2
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
if [ "$mode" = "status" ]; then
|
|
107
|
+
if [ "$non_interactive" != false ] || [ "$debug" != false ] || [ -n "$package_name$command_name$description$license$copyright_holder$repository" ]; then
|
|
108
|
+
printf '%s\n' '{"schemaVersion":1,"currentStage":{"id":"check-prerequisites","number":1,"name":"Check prerequisites"},"observations":{"packagePath":null,"packageName":null,"commandName":null,"version":null,"repository":null,"readiness":"unavailable","git":{"workingTree":null,"currentBranch":null,"defaultBranch":null,"headMatchesRemoteDefault":null}},"blockers":[{"code":"publication-setup-usage","observed":"invalid status arguments","expected":"--status --json only","nextAction":"Run ./scripts/npm-publication-setup/setup.sh --status --json."}],"nextAction":{"kind":"run","command":"./scripts/npm-publication-setup/setup.sh"}}'
|
|
109
|
+
exit 2
|
|
110
|
+
fi
|
|
111
|
+
REPOSITORY_ROOT="$repository_root" node --conditions=source "$script_dir/bridge.ts" status
|
|
112
|
+
exit $?
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
cd "$repository_root" || fail ERROR repository-root "unreadable repository root" "the generated repository root" "Run setup from its generated directory." 5
|
|
116
|
+
printf 'STAGE 1/9 Check prerequisites\nCHECK local-toolchain\n'
|
|
117
|
+
for command in bash node pnpm git gh; do command -v "$command" >/dev/null 2>&1 || fail ERROR prerequisite-command "$command is unavailable" "required local command $command" "Install the generated repository toolchain and retry." 5; done
|
|
118
|
+
REPOSITORY_ROOT="$repository_root" node --conditions=source "$script_dir/bridge.ts" preflight
|
|
119
|
+
preflight_status=$?
|
|
120
|
+
[ "$preflight_status" -eq 0 ] || exit "$preflight_status"
|
|
121
|
+
printf 'OK prerequisites\n'
|
|
122
|
+
|
|
123
|
+
existing_public=false
|
|
124
|
+
if node --input-type=module - "$repository_root/$package_path/package.json" <<'NODE' >/dev/null 2>&1
|
|
125
|
+
import { readFileSync } from "node:fs"; const manifest = JSON.parse(readFileSync(process.argv[2], "utf8")); process.exit(manifest.private || manifest.version !== "1.0.0" ? 1 : 0);
|
|
126
|
+
NODE
|
|
127
|
+
then
|
|
128
|
+
existing_public=true
|
|
129
|
+
fi
|
|
130
|
+
if [ "$non_interactive" = false ] && [ "$existing_public" = false ]; then
|
|
131
|
+
[ -n "$package_name" ] || prompt_public_fact "Package name" package_name
|
|
132
|
+
[ -n "$command_name" ] || prompt_public_fact "Command name" command_name
|
|
133
|
+
[ -n "$description" ] || prompt_public_fact "Public description" description
|
|
134
|
+
[ -n "$license" ] || prompt_public_fact "SPDX license" license
|
|
135
|
+
[ -n "$copyright_holder" ] || prompt_public_fact "Copyright holder" copyright_holder
|
|
136
|
+
[ -n "$repository" ] || prompt_public_fact "Public GitHub repository" repository
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
printf 'STAGE 2/9 Configure the public package\n'
|
|
140
|
+
PACKAGE_NAME="$package_name" COMMAND_NAME="$command_name" DESCRIPTION="$description" LICENSE_NAME="$license" COPYRIGHT_HOLDER="$copyright_holder" REPOSITORY_URL="$repository" REPOSITORY_ROOT="$repository_root" SETUP_DIR="$script_dir" node --conditions=source "$script_dir/bridge.ts" configure
|
|
141
|
+
configuration_status=$?
|
|
142
|
+
[ "$configuration_status" -eq 0 ] || exit "$configuration_status"
|
|
143
|
+
printf 'OK public-package-configured\nSTAGE 3/9 Commit the publication configuration\n'
|
|
144
|
+
if ! working_tree=$(git status --porcelain 2>/dev/null); then
|
|
145
|
+
fail ERROR git-read-unavailable "working tree could not be read" "readable local Git facts" "Correct the Git or platform failure and retry." 5
|
|
146
|
+
fi
|
|
147
|
+
if [ -n "$working_tree" ]; then fail "ACTION REQUIRED" git-handoff-required "publication configuration needs normal Git review" "a clean synchronized public default branch" "Use the normal review, commit, PR, and merge flow; then rerun setup." 3; fi
|
|
148
|
+
branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null)
|
|
149
|
+
branch_status=$?
|
|
150
|
+
if [ "$branch_status" -eq 1 ]; then
|
|
151
|
+
fail "ACTION REQUIRED" git-handoff-required "HEAD is detached" "a checked-out public default branch" "Complete the normal Git handoff and rerun setup." 3
|
|
152
|
+
fi
|
|
153
|
+
if [ "$branch_status" -ne 0 ]; then
|
|
154
|
+
fail ERROR git-read-unavailable "current branch could not be read" "readable local Git facts" "Correct the Git or platform failure and retry." 5
|
|
155
|
+
fi
|
|
156
|
+
if ! remote=$(git remote get-url origin 2>/dev/null); then
|
|
157
|
+
fail ERROR git-read-unavailable "origin could not be read" "a readable public origin" "Correct the Git or platform failure and retry." 5
|
|
158
|
+
fi
|
|
159
|
+
if ! remote_listing=$(git ls-remote --symref origin HEAD 2>/dev/null); then
|
|
160
|
+
fail ERROR git-read-unavailable "remote default branch could not be read" "a reachable public origin" "Correct the Git or network failure and retry." 5
|
|
161
|
+
fi
|
|
162
|
+
remote_default=$(printf '%s\n' "$remote_listing" | sed -n 's#ref: refs/heads/\([^[:space:]]*\).*#\1#p' | head -n 1)
|
|
163
|
+
if [ -z "$remote_default" ]; then
|
|
164
|
+
fail "ACTION REQUIRED" git-handoff-required "remote default branch is unavailable" "a public default branch" "Complete the normal Git handoff and rerun setup." 3
|
|
165
|
+
fi
|
|
166
|
+
if ! remote_head=$(git ls-remote origin "refs/heads/$remote_default" 2>/dev/null); then
|
|
167
|
+
fail ERROR git-read-unavailable "remote default HEAD could not be read" "a reachable public origin" "Correct the Git or network failure and retry." 5
|
|
168
|
+
fi
|
|
169
|
+
remote_head=$(printf '%s\n' "$remote_head" | awk 'NR==1 {print $1}')
|
|
170
|
+
if ! local_head=$(git rev-parse HEAD 2>/dev/null); then
|
|
171
|
+
fail ERROR git-read-unavailable "local HEAD could not be read" "a readable local HEAD" "Correct the Git or platform failure and retry." 5
|
|
172
|
+
fi
|
|
173
|
+
if [ "$branch" != "$remote_default" ] || [ -z "$remote_head" ] || [ "$local_head" != "$remote_head" ]; then
|
|
174
|
+
fail "ACTION REQUIRED" git-handoff-required "branch or remote is not synchronized" "clean public default branch at its remote HEAD" "Complete the normal Git handoff and rerun setup." 3
|
|
175
|
+
fi
|
|
176
|
+
if ! REMOTE_URL="$remote" REPOSITORY_ROOT="$repository_root" node --conditions=source "$script_dir/bridge.ts" remote-matches-owner; then
|
|
177
|
+
fail ERROR repository-remote-conflict "$(printf '%s' "$remote" | redact)" "the public package owner GitHub repository" "Correct the normal Git remote and retry." 4
|
|
178
|
+
fi
|
|
179
|
+
printf 'OK git-handoff-complete\nSTAGE 4/9 Verify the first release artifact\n'
|
|
180
|
+
artifact_parent_input=${TMPDIR:-/tmp}
|
|
181
|
+
if ! artifact_parent=$(CDPATH='' cd -- "$artifact_parent_input" && pwd -P); then
|
|
182
|
+
fail ERROR artifact-temporary-output "temporary parent is unreadable" "a readable local temporary directory" "Correct TMPDIR permissions and retry." 5
|
|
183
|
+
fi
|
|
184
|
+
artifact_root=$(mktemp -d "$artifact_parent/npm-publication-setup-artifact.XXXXXX") || fail ERROR artifact-temporary-output "unable to create temporary output" "an empty local temporary directory" "Correct temporary directory permissions and retry." 5
|
|
185
|
+
artifact_cleaned=false
|
|
186
|
+
cleanup_artifact_root() {
|
|
187
|
+
[ "$artifact_cleaned" = true ] && return 0
|
|
188
|
+
case "$artifact_root" in
|
|
189
|
+
"$artifact_parent"/npm-publication-setup-artifact.*) ;;
|
|
190
|
+
*) return 1 ;;
|
|
191
|
+
esac
|
|
192
|
+
[ "$(dirname -- "$artifact_root")" = "$artifact_parent" ] || return 1
|
|
193
|
+
[ ! -e "$artifact_root" ] && [ ! -L "$artifact_root" ] || {
|
|
194
|
+
[ -d "$artifact_root" ] && [ ! -L "$artifact_root" ] || return 1
|
|
195
|
+
rm -rf -- "$artifact_root" || return 1
|
|
196
|
+
}
|
|
197
|
+
artifact_cleaned=true
|
|
198
|
+
}
|
|
199
|
+
cleanup_artifact_best_effort() {
|
|
200
|
+
cleanup_artifact_root >/dev/null 2>&1 || :
|
|
201
|
+
}
|
|
202
|
+
trap cleanup_artifact_best_effort EXIT HUP INT TERM
|
|
203
|
+
if [ "$debug" = true ]; then printf 'COMMAND %s\n' "verifyNpmPublicationArtifact [temporary output]"; fi
|
|
204
|
+
artifact_result=$(REPOSITORY_ROOT="$repository_root" ARTIFACT_OUTPUT_DIRECTORY="$artifact_root" node --conditions=source "$script_dir/bridge.ts" artifact)
|
|
205
|
+
artifact_status=$?
|
|
206
|
+
if [ "$artifact_status" -ne 0 ]; then
|
|
207
|
+
printf '%s\n' "$artifact_result" >&2
|
|
208
|
+
exit "$artifact_status"
|
|
209
|
+
fi
|
|
210
|
+
printf '%s\n' "$artifact_result" | sed '$d'
|
|
211
|
+
acceptance=$(printf '%s\n' "$artifact_result" | tail -n 1)
|
|
212
|
+
if [ "$non_interactive" = true ]; then fail "ACTION REQUIRED" artifact-acceptance-required "non-interactive mode cannot accept an artifact" "$acceptance" "Review the receipt and enter the exact acceptance interactively." 3; fi
|
|
213
|
+
printf '%s\n' "$acceptance"; printf 'Acceptance: '; read -r entered || fail "ACTION REQUIRED" artifact-acceptance-required "end of input" "$acceptance" "Review the receipt and enter the exact acceptance." 3
|
|
214
|
+
[ "$entered" = "$acceptance" ] || fail "ACTION REQUIRED" artifact-acceptance-required "acceptance did not match this receipt" "$acceptance" "Review the receipt and enter the exact acceptance." 3
|
|
215
|
+
# A successful exec is the ownership boundary: before it, this shell owns the
|
|
216
|
+
# accepted artifact; after it, the private bridge owns the artifact, session,
|
|
217
|
+
# signal handling, logout, and cleanup as one linear lifecycle.
|
|
218
|
+
REPOSITORY_ROOT="$repository_root" ARTIFACT_ROOT="$artifact_root" DEBUG="$debug" \
|
|
219
|
+
exec node --conditions=source "$script_dir/bridge.ts" external
|
|
220
|
+
exec_status=$?
|
|
221
|
+
fail ERROR external-bridge-unavailable "could not transfer the accepted artifact to the private setup bridge" "a runnable private setup bridge" "Correct the generated setup files and retry." "$exec_status"
|
package/node_modules/@ykdz/template-builtin-presets/templates/ts-cli/src/cli-command-identity.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export type CliCommandIdentity = {
|
|
2
|
+
readonly commandName: string;
|
|
3
|
+
readonly version: string;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
const reservedSystemToolNames = new Set([
|
|
7
|
+
"aux",
|
|
8
|
+
"bash",
|
|
9
|
+
"bun",
|
|
10
|
+
"cmd",
|
|
11
|
+
"com1",
|
|
12
|
+
"com2",
|
|
13
|
+
"com3",
|
|
14
|
+
"com4",
|
|
15
|
+
"com5",
|
|
16
|
+
"com6",
|
|
17
|
+
"com7",
|
|
18
|
+
"com8",
|
|
19
|
+
"com9",
|
|
20
|
+
"con",
|
|
21
|
+
"corepack",
|
|
22
|
+
"deno",
|
|
23
|
+
"git",
|
|
24
|
+
"lpt1",
|
|
25
|
+
"lpt2",
|
|
26
|
+
"lpt3",
|
|
27
|
+
"lpt4",
|
|
28
|
+
"lpt5",
|
|
29
|
+
"lpt6",
|
|
30
|
+
"lpt7",
|
|
31
|
+
"lpt8",
|
|
32
|
+
"lpt9",
|
|
33
|
+
"node",
|
|
34
|
+
"nul",
|
|
35
|
+
"npm",
|
|
36
|
+
"npx",
|
|
37
|
+
"pnpm",
|
|
38
|
+
"powershell",
|
|
39
|
+
"prn",
|
|
40
|
+
"pwsh",
|
|
41
|
+
"sh",
|
|
42
|
+
"yarn",
|
|
43
|
+
"zsh",
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
export function validateCliCommandName(
|
|
47
|
+
commandName: string,
|
|
48
|
+
occupiedCommandNames: readonly string[] = [],
|
|
49
|
+
): string {
|
|
50
|
+
if (/[/\\]/u.test(commandName)) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`CLI command name must not be a path; received ${JSON.stringify(commandName)}`,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
if (/\p{White_Space}/u.test(commandName)) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
`CLI command name must not contain whitespace; received ${JSON.stringify(commandName)}`,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
if (/\p{Control}/u.test(commandName)) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
`CLI command name must not contain a control character; received ${JSON.stringify(commandName)}`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
if (commandName.startsWith("-")) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
`CLI command name must not have a leading hyphen; received ${JSON.stringify(commandName)}`,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(commandName)) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
`CLI command name must use lowercase ASCII letters, digits, and single hyphens; received ${JSON.stringify(commandName)}`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
if (reservedSystemToolNames.has(commandName)) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
`CLI command name is a reserved system tool; received ${JSON.stringify(commandName)}`,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
if (occupiedCommandNames.includes(commandName)) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`CLI command name is already used by another workspace package; received ${JSON.stringify(commandName)}`,
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return commandName;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function cliCommandIdentity(
|
|
89
|
+
manifest: unknown,
|
|
90
|
+
occupiedCommandNames: readonly string[] = [],
|
|
91
|
+
): CliCommandIdentity {
|
|
92
|
+
if (
|
|
93
|
+
typeof manifest !== "object" ||
|
|
94
|
+
manifest === null ||
|
|
95
|
+
Array.isArray(manifest)
|
|
96
|
+
) {
|
|
97
|
+
throw new Error("CLI package manifest must be an object");
|
|
98
|
+
}
|
|
99
|
+
const manifestFacts = manifest as Readonly<Record<string, unknown>>;
|
|
100
|
+
if (
|
|
101
|
+
typeof manifestFacts.bin !== "object" ||
|
|
102
|
+
manifestFacts.bin === null ||
|
|
103
|
+
Array.isArray(manifestFacts.bin)
|
|
104
|
+
) {
|
|
105
|
+
throw new Error("CLI package manifest must declare exactly one bin");
|
|
106
|
+
}
|
|
107
|
+
const binEntries = Object.entries(manifestFacts.bin);
|
|
108
|
+
if (binEntries.length !== 1) {
|
|
109
|
+
throw new Error("CLI package manifest must declare exactly one bin");
|
|
110
|
+
}
|
|
111
|
+
const [commandName, executable] = binEntries[0]!;
|
|
112
|
+
if (executable !== "./dist/cli.js") {
|
|
113
|
+
throw new Error('CLI package manifest bin must execute "./dist/cli.js"');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let version = "unpublished";
|
|
117
|
+
if (manifestFacts.version !== undefined) {
|
|
118
|
+
if (
|
|
119
|
+
typeof manifestFacts.version !== "string" ||
|
|
120
|
+
manifestFacts.version.length === 0
|
|
121
|
+
) {
|
|
122
|
+
throw new Error(
|
|
123
|
+
"CLI package manifest version must be a non-empty string when present",
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
version = manifestFacts.version;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
commandName: validateCliCommandName(commandName, occupiedCommandNames),
|
|
131
|
+
version,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { cliCommandIdentity } from "./cli-command-identity.ts";
|
|
5
|
+
import { runCli, type CliRuntime } from "./main.ts";
|
|
5
6
|
|
|
6
7
|
const require = createRequire(import.meta.url);
|
|
7
|
-
const packageManifest = require("../package.json") as
|
|
8
|
+
const packageManifest = require("../package.json") as unknown;
|
|
8
9
|
|
|
9
10
|
const runtime: CliRuntime = {
|
|
10
11
|
argv: process.argv,
|
|
@@ -20,7 +21,7 @@ const runtime: CliRuntime = {
|
|
|
20
21
|
stdout: Boolean(process.stdout.isTTY),
|
|
21
22
|
stderr: Boolean(process.stderr.isTTY),
|
|
22
23
|
},
|
|
23
|
-
|
|
24
|
+
identity: cliCommandIdentity(packageManifest),
|
|
24
25
|
};
|
|
25
26
|
|
|
26
27
|
process.exitCode = await runCli(runtime);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command, CommanderError } from "commander";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import type { CliCommandIdentity } from "./cli-command-identity.ts";
|
|
4
|
+
|
|
4
5
|
export type Greeting = {
|
|
5
6
|
readonly message: string;
|
|
6
7
|
};
|
|
@@ -19,7 +20,7 @@ export type CliRuntime = {
|
|
|
19
20
|
readonly stdout: boolean;
|
|
20
21
|
readonly stderr: boolean;
|
|
21
22
|
};
|
|
22
|
-
readonly
|
|
23
|
+
readonly identity: CliCommandIdentity;
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
export function greet(name: string): Greeting {
|
|
@@ -36,9 +37,9 @@ function errorMessage(error: unknown): string {
|
|
|
36
37
|
|
|
37
38
|
export function createCliCommand(runtime: CliRuntime): Command {
|
|
38
39
|
const command = new Command()
|
|
39
|
-
.name(commandName)
|
|
40
|
+
.name(runtime.identity.commandName)
|
|
40
41
|
.description("A TypeScript command-line tool.")
|
|
41
|
-
.version(runtime.version)
|
|
42
|
+
.version(runtime.identity.version)
|
|
42
43
|
.configureOutput({
|
|
43
44
|
writeOut: (text) => runtime.streams.stdout.write(text),
|
|
44
45
|
writeErr: (text) => runtime.streams.stderr.write(text),
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
|
|
1
3
|
import { describe, expect, it } from "vitest";
|
|
2
4
|
|
|
5
|
+
import { cliCommandIdentity } from "../../src/cli-command-identity.ts";
|
|
3
6
|
import { runCli, type CliRuntime } from "../../src/main.ts";
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const packageManifest = require("../../package.json") as unknown;
|
|
10
|
+
const identity = cliCommandIdentity(packageManifest);
|
|
7
11
|
|
|
8
|
-
function testRuntime(
|
|
9
|
-
args: readonly string[],
|
|
10
|
-
version = "1.2.3",
|
|
11
|
-
): {
|
|
12
|
+
function testRuntime(args: readonly string[]): {
|
|
12
13
|
readonly runtime: CliRuntime;
|
|
13
14
|
readonly stdout: () => string;
|
|
14
15
|
readonly stderr: () => string;
|
|
@@ -17,7 +18,7 @@ function testRuntime(
|
|
|
17
18
|
let stderr = "";
|
|
18
19
|
return {
|
|
19
20
|
runtime: {
|
|
20
|
-
argv: ["node", commandName, ...args],
|
|
21
|
+
argv: ["node", identity.commandName, ...args],
|
|
21
22
|
streams: {
|
|
22
23
|
stdin: {},
|
|
23
24
|
stdout: { write: (chunk) => (stdout += chunk) },
|
|
@@ -26,7 +27,7 @@ function testRuntime(
|
|
|
26
27
|
cwd: "/workspace",
|
|
27
28
|
env: { MODE: "test" },
|
|
28
29
|
tty: { stdin: false, stdout: false, stderr: false },
|
|
29
|
-
|
|
30
|
+
identity,
|
|
30
31
|
},
|
|
31
32
|
stdout: () => stdout,
|
|
32
33
|
stderr: () => stderr,
|
|
@@ -42,11 +43,11 @@ describe("CLI command control", () => {
|
|
|
42
43
|
expect(output.stderr()).toBe("");
|
|
43
44
|
});
|
|
44
45
|
|
|
45
|
-
it("renders the
|
|
46
|
-
const output = testRuntime(["--version"]
|
|
46
|
+
it("renders the version derived from the package manifest", async () => {
|
|
47
|
+
const output = testRuntime(["--version"]);
|
|
47
48
|
|
|
48
49
|
await expect(runCli(output.runtime)).resolves.toBe(0);
|
|
49
|
-
expect(output.stdout()).toBe(
|
|
50
|
+
expect(output.stdout()).toBe(`${identity.version}\n`);
|
|
50
51
|
expect(output.stderr()).toBe("");
|
|
51
52
|
});
|
|
52
53
|
|
|
@@ -55,7 +56,7 @@ describe("CLI command control", () => {
|
|
|
55
56
|
|
|
56
57
|
await expect(runCli(output.runtime)).resolves.toBe(0);
|
|
57
58
|
expect(output.stdout()).toContain(
|
|
58
|
-
`Usage: ${commandName} [options] [command]`,
|
|
59
|
+
`Usage: ${identity.commandName} [options] [command]`,
|
|
59
60
|
);
|
|
60
61
|
expect(output.stdout()).toContain("greet <name>");
|
|
61
62
|
expect(output.stderr()).toBe("");
|
|
@@ -69,7 +70,7 @@ describe("CLI command control", () => {
|
|
|
69
70
|
expect(output.stderr()).toContain(
|
|
70
71
|
"error: missing required argument 'name'",
|
|
71
72
|
);
|
|
72
|
-
expect(output.stderr()).toContain(`Usage: ${commandName} greet`);
|
|
73
|
+
expect(output.stderr()).toContain(`Usage: ${identity.commandName} greet`);
|
|
73
74
|
});
|
|
74
75
|
|
|
75
76
|
it("adapts business validation into a testable command error", async () => {
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
cliCommandIdentity,
|
|
5
|
+
validateCliCommandName,
|
|
6
|
+
} from "../../src/cli-command-identity.ts";
|
|
7
|
+
|
|
8
|
+
describe("CLI command identity", () => {
|
|
9
|
+
it.each([
|
|
10
|
+
{ name: "path separator", command: "tools/release", message: "path" },
|
|
11
|
+
{ name: "backslash path", command: "tools\\release", message: "path" },
|
|
12
|
+
{ name: "whitespace", command: "release tool", message: "whitespace" },
|
|
13
|
+
{ name: "control character", command: "release\u0000", message: "control" },
|
|
14
|
+
{ name: "leading hyphen", command: "-release", message: "leading hyphen" },
|
|
15
|
+
{ name: "uppercase ASCII", command: "Release", message: "lowercase ASCII" },
|
|
16
|
+
{ name: "non-ASCII", command: "发布", message: "lowercase ASCII" },
|
|
17
|
+
{ name: "system tool", command: "node", message: "reserved system tool" },
|
|
18
|
+
{ name: "Windows device", command: "con", message: "reserved system tool" },
|
|
19
|
+
{
|
|
20
|
+
name: "Windows null device",
|
|
21
|
+
command: "nul",
|
|
22
|
+
message: "reserved system tool",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "Windows serial device",
|
|
26
|
+
command: "com1",
|
|
27
|
+
message: "reserved system tool",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "Windows printer device",
|
|
31
|
+
command: "lpt9",
|
|
32
|
+
message: "reserved system tool",
|
|
33
|
+
},
|
|
34
|
+
])("rejects an unsafe command name: $name", ({ command, message }) => {
|
|
35
|
+
expect(() => validateCliCommandName(command)).toThrow(message);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("accepts a portable name unless another workspace command occupies it", () => {
|
|
39
|
+
expect(validateCliCommandName("release-tool", [])).toBe("release-tool");
|
|
40
|
+
expect(() =>
|
|
41
|
+
validateCliCommandName("release-tool", ["release-tool"]),
|
|
42
|
+
).toThrow("already used by another workspace package");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("derives command and unpublished version only from manifest facts", () => {
|
|
46
|
+
expect(cliCommandIdentity({ bin: { release: "./dist/cli.js" } })).toEqual({
|
|
47
|
+
commandName: "release",
|
|
48
|
+
version: "unpublished",
|
|
49
|
+
});
|
|
50
|
+
expect(
|
|
51
|
+
cliCommandIdentity({
|
|
52
|
+
bin: { ship: "./dist/cli.js" },
|
|
53
|
+
version: "2.3.4",
|
|
54
|
+
}),
|
|
55
|
+
).toEqual({ commandName: "ship", version: "2.3.4" });
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("rejects malformed manifest identity facts", () => {
|
|
59
|
+
expect(() => cliCommandIdentity(null)).toThrow("must be an object");
|
|
60
|
+
expect(() => cliCommandIdentity({ bin: {} })).toThrow("exactly one bin");
|
|
61
|
+
expect(() =>
|
|
62
|
+
cliCommandIdentity({
|
|
63
|
+
bin: { release: "./dist/cli.js", ship: "./dist/cli.js" },
|
|
64
|
+
}),
|
|
65
|
+
).toThrow("exactly one bin");
|
|
66
|
+
expect(() =>
|
|
67
|
+
cliCommandIdentity({ bin: { release: "./src/cli.ts" } }),
|
|
68
|
+
).toThrow('must execute "./dist/cli.js"');
|
|
69
|
+
expect(() =>
|
|
70
|
+
cliCommandIdentity({
|
|
71
|
+
bin: { release: "./dist/cli.js" },
|
|
72
|
+
version: 1,
|
|
73
|
+
}),
|
|
74
|
+
).toThrow("version must be a non-empty string");
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -13,7 +13,7 @@ export function assertDatabaseReady(db: Database) {
|
|
|
13
13
|
throw new Error(
|
|
14
14
|
[
|
|
15
15
|
"Database is not ready.",
|
|
16
|
-
"For local development, run `pnpm --dir
|
|
16
|
+
"For local development, run `pnpm --dir apps/web dev`.",
|
|
17
17
|
"For deployment, run `pnpm --dir packages/db-migrations run db:prepare:deploy` before starting the app.",
|
|
18
18
|
].join(" "),
|
|
19
19
|
{ cause },
|
package/node_modules/@ykdz/template-builtin-presets/templates/vike-app/db/test/global-setup.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { rmSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
const packageRoot = path.resolve(import.meta.dirname, "..");
|
|
6
|
+
const migrationsRoot = path.resolve(packageRoot, "../db-migrations");
|
|
7
|
+
const databaseFile = path.join(packageRoot, "node_modules/.tmp/test.sqlite");
|
|
8
|
+
|
|
9
|
+
export function setup(): void {
|
|
10
|
+
rmSync(databaseFile, { force: true });
|
|
11
|
+
process.env.DATABASE_FILE = databaseFile;
|
|
12
|
+
execFileSync("pnpm", ["run", "db:push"], {
|
|
13
|
+
cwd: migrationsRoot,
|
|
14
|
+
env: process.env,
|
|
15
|
+
stdio: "inherit",
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function teardown(): void {
|
|
20
|
+
rmSync(databaseFile, { force: true });
|
|
21
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { mkdirSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
1
3
|
import { fileURLToPath } from "node:url";
|
|
2
4
|
|
|
3
5
|
import { defineConfig } from "drizzle-kit";
|
|
@@ -6,12 +8,14 @@ const databasePackageName = process.env.DATABASE_PACKAGE_NAME ?? "@database";
|
|
|
6
8
|
const schemaFile = fileURLToPath(
|
|
7
9
|
import.meta.resolve(`${databasePackageName}/schema`),
|
|
8
10
|
);
|
|
11
|
+
const databaseFile = process.env.DATABASE_FILE ?? "./data/app.sqlite";
|
|
12
|
+
mkdirSync(path.dirname(databaseFile), { recursive: true });
|
|
9
13
|
|
|
10
14
|
export default defineConfig({
|
|
11
15
|
dialect: "sqlite",
|
|
12
16
|
schema: schemaFile,
|
|
13
17
|
out: "./drizzle/migrations",
|
|
14
18
|
dbCredentials: {
|
|
15
|
-
url:
|
|
19
|
+
url: databaseFile,
|
|
16
20
|
},
|
|
17
21
|
});
|