@arkvenai/cli 0.5.1
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 +105 -0
- package/README.md +304 -0
- package/dist/agents.d.ts +11 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +76 -0
- package/dist/agents.js.map +1 -0
- package/dist/auftrag.d.ts +3 -0
- package/dist/auftrag.d.ts.map +1 -0
- package/dist/auftrag.js +45 -0
- package/dist/auftrag.js.map +1 -0
- package/dist/bauplan.d.ts +15 -0
- package/dist/bauplan.d.ts.map +1 -0
- package/dist/bauplan.js +219 -0
- package/dist/bauplan.js.map +1 -0
- package/dist/befehle.d.ts +12 -0
- package/dist/befehle.d.ts.map +1 -0
- package/dist/befehle.js +77 -0
- package/dist/befehle.js.map +1 -0
- package/dist/befund.d.ts +21 -0
- package/dist/befund.d.ts.map +1 -0
- package/dist/befund.js +107 -0
- package/dist/befund.js.map +1 -0
- package/dist/codeAblage.d.ts +31 -0
- package/dist/codeAblage.d.ts.map +1 -0
- package/dist/codeAblage.js +80 -0
- package/dist/codeAblage.js.map +1 -0
- package/dist/deklaration.d.ts +3 -0
- package/dist/deklaration.d.ts.map +1 -0
- package/dist/deklaration.js +14 -0
- package/dist/deklaration.js.map +1 -0
- package/dist/diff.d.ts +10 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +72 -0
- package/dist/diff.js.map +1 -0
- package/dist/erkennung.d.ts +26 -0
- package/dist/erkennung.d.ts.map +1 -0
- package/dist/erkennung.js +174 -0
- package/dist/erkennung.js.map +1 -0
- package/dist/fix.d.ts +26 -0
- package/dist/fix.d.ts.map +1 -0
- package/dist/fix.js +101 -0
- package/dist/fix.js.map +1 -0
- package/dist/geteilt/bauplan/form.d.ts +100 -0
- package/dist/geteilt/bauplan/form.d.ts.map +1 -0
- package/dist/geteilt/bauplan/form.js +21 -0
- package/dist/geteilt/bauplan/form.js.map +1 -0
- package/dist/geteilt/bauplan/index.d.ts +4 -0
- package/dist/geteilt/bauplan/index.d.ts.map +1 -0
- package/dist/geteilt/bauplan/index.js +4 -0
- package/dist/geteilt/bauplan/index.js.map +1 -0
- package/dist/geteilt/bauplan/lesen.d.ts +6 -0
- package/dist/geteilt/bauplan/lesen.d.ts.map +1 -0
- package/dist/geteilt/bauplan/lesen.js +344 -0
- package/dist/geteilt/bauplan/lesen.js.map +1 -0
- package/dist/geteilt/bauplan/schreiben.d.ts +3 -0
- package/dist/geteilt/bauplan/schreiben.d.ts.map +1 -0
- package/dist/geteilt/bauplan/schreiben.js +80 -0
- package/dist/geteilt/bauplan/schreiben.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +352 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +28 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +324 -0
- package/dist/init.js.map +1 -0
- package/dist/login.d.ts +45 -0
- package/dist/login.d.ts.map +1 -0
- package/dist/login.js +162 -0
- package/dist/login.js.map +1 -0
- package/dist/mcp.d.ts +18 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +115 -0
- package/dist/mcp.js.map +1 -0
- package/dist/neu.d.ts +17 -0
- package/dist/neu.d.ts.map +1 -0
- package/dist/neu.js +118 -0
- package/dist/neu.js.map +1 -0
- package/dist/npmrc.d.ts +9 -0
- package/dist/npmrc.d.ts.map +1 -0
- package/dist/npmrc.js +49 -0
- package/dist/npmrc.js.map +1 -0
- package/dist/projekte.d.ts +23 -0
- package/dist/projekte.d.ts.map +1 -0
- package/dist/projekte.js +82 -0
- package/dist/projekte.js.map +1 -0
- package/dist/pull.d.ts +15 -0
- package/dist/pull.d.ts.map +1 -0
- package/dist/pull.js +301 -0
- package/dist/pull.js.map +1 -0
- package/dist/push/bericht.d.ts +8 -0
- package/dist/push/bericht.d.ts.map +1 -0
- package/dist/push/bericht.js +85 -0
- package/dist/push/bericht.js.map +1 -0
- package/dist/push/form.d.ts +67 -0
- package/dist/push/form.d.ts.map +1 -0
- package/dist/push/form.js +6 -0
- package/dist/push/form.js.map +1 -0
- package/dist/push/medien.d.ts +7 -0
- package/dist/push/medien.d.ts.map +1 -0
- package/dist/push/medien.js +154 -0
- package/dist/push/medien.js.map +1 -0
- package/dist/push/sammeln.d.ts +34 -0
- package/dist/push/sammeln.d.ts.map +1 -0
- package/dist/push/sammeln.js +112 -0
- package/dist/push/sammeln.js.map +1 -0
- package/dist/push/verzeichnisse.d.ts +40 -0
- package/dist/push/verzeichnisse.d.ts.map +1 -0
- package/dist/push/verzeichnisse.js +158 -0
- package/dist/push/verzeichnisse.js.map +1 -0
- package/dist/push.d.ts +8 -0
- package/dist/push.d.ts.map +1 -0
- package/dist/push.js +306 -0
- package/dist/push.js.map +1 -0
- package/dist/starter.d.ts +4 -0
- package/dist/starter.d.ts.map +1 -0
- package/dist/starter.js +587 -0
- package/dist/starter.js.map +1 -0
- package/dist/tiefpruefung.d.ts +39 -0
- package/dist/tiefpruefung.d.ts.map +1 -0
- package/dist/tiefpruefung.js +56 -0
- package/dist/tiefpruefung.js.map +1 -0
- package/dist/vertrag.d.ts +6 -0
- package/dist/vertrag.d.ts.map +1 -0
- package/dist/vertrag.js +267 -0
- package/dist/vertrag.js.map +1 -0
- package/dist/vertragSpaet.d.ts +4 -0
- package/dist/vertragSpaet.d.ts.map +1 -0
- package/dist/vertragSpaet.js +158 -0
- package/dist/vertragSpaet.js.map +1 -0
- package/dist/vorlagen.d.ts +7 -0
- package/dist/vorlagen.d.ts.map +1 -0
- package/dist/vorlagen.js +83 -0
- package/dist/vorlagen.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { leseZugang, STANDARD_SERVER } from './login.js';
|
|
2
|
+
export async function tiefPruefen(dateien, serverDateien, opts = {}) {
|
|
3
|
+
const zugang = leseZugang();
|
|
4
|
+
if (!zugang?.cliToken) {
|
|
5
|
+
return {
|
|
6
|
+
erreichbar: false,
|
|
7
|
+
grund: 'Dieser Rechner ist nicht bei Arkven angemeldet, deshalb laufen die Plattform-Gates nicht mit.\n' +
|
|
8
|
+
'So kommst du weiter: `arkven login`.',
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
const server = (opts.server || zugang.server || STANDARD_SERVER).replace(/\/+$/, '');
|
|
12
|
+
try {
|
|
13
|
+
const res = await fetch(`${server}/api/projekte/pruefen`, {
|
|
14
|
+
method: 'POST',
|
|
15
|
+
headers: { 'content-type': 'application/json', authorization: `Bearer ${zugang.cliToken}` },
|
|
16
|
+
body: JSON.stringify({ dateien, serverDateien }),
|
|
17
|
+
});
|
|
18
|
+
const daten = (await res.json().catch(() => ({})));
|
|
19
|
+
if (!res.ok) {
|
|
20
|
+
return {
|
|
21
|
+
erreichbar: false,
|
|
22
|
+
grund: `${daten.error ?? `Arkven antwortete mit Status ${res.status}.`}${daten.ausweg ? `
|
|
23
|
+
So kommst du weiter: ${daten.ausweg}` : ''}`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
erreichbar: true,
|
|
28
|
+
ergebnis: {
|
|
29
|
+
ok: daten.ok === true,
|
|
30
|
+
checks: daten.checks ?? [],
|
|
31
|
+
ungeprueft: daten.ungeprueft ?? [],
|
|
32
|
+
...(daten.mailArten ? { mailArten: daten.mailArten } : {}),
|
|
33
|
+
...(daten.screens ? { screens: daten.screens } : {}),
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
return { erreichbar: false, grund: `Arkven war nicht erreichbar: ${String(e?.message ?? e)}` };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export function alsBefunde(e) {
|
|
42
|
+
const out = [];
|
|
43
|
+
for (const c of e.checks) {
|
|
44
|
+
if (c.ok)
|
|
45
|
+
continue;
|
|
46
|
+
out.push({
|
|
47
|
+
regel: c.regel ?? 'arkven/plattform-gate',
|
|
48
|
+
schwere: c.required ? 'vertrag' : 'hinweis',
|
|
49
|
+
titel: c.details ? `${c.name}: ${c.details}` : c.name,
|
|
50
|
+
...(c.ort ? { ort: c.ort } : {}),
|
|
51
|
+
ausweg: c.ausweg ?? 'Der Befund kommt aus den Gates der Plattform. Dieselbe Prüfung läuft beim Ausrollen.',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=tiefpruefung.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tiefpruefung.js","sourceRoot":"","sources":["../src/tiefpruefung.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Ergebnis } from './befund.js';
|
|
2
|
+
export declare function lies(p: string): string | undefined;
|
|
3
|
+
export declare function quelltext(wurzel: string): string;
|
|
4
|
+
export declare function serverKandidaten(wurzel: string): string[];
|
|
5
|
+
export declare function pruefeVertrag(wurzel: string): Ergebnis;
|
|
6
|
+
//# sourceMappingURL=vertrag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vertrag.d.ts","sourceRoot":"","sources":["../src/vertrag.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAU,QAAQ,EAAE,MAAM,aAAa,CAAA;AA8BnD,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMlD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAmBhD;AAYD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAezD;AASD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAuNtD"}
|
package/dist/vertrag.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { builtinModules } from 'node:module';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { pruefeSpaeteFallen } from './vertragSpaet.js';
|
|
5
|
+
const EINGEBAUT = new Set(builtinModules);
|
|
6
|
+
const IMPORT_RE = /(?:^|\s)(?:import|export)\s+(?:[\s\S]*?\sfrom\s+)?['"]([^'"]+)['"]/gm;
|
|
7
|
+
const IMPORT_DYN_RE = /\bimport\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
8
|
+
const IMPORT_REQUIRE_RE = /\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
9
|
+
function nurCode(src) {
|
|
10
|
+
return src
|
|
11
|
+
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
12
|
+
.replace(/^\s*\/\/.*$/gm, '')
|
|
13
|
+
.replace(/`(?:[^`\\]|\\[\s\S])*`/g, '``');
|
|
14
|
+
}
|
|
15
|
+
function paketName(spez) {
|
|
16
|
+
if (spez.startsWith('.') || spez.startsWith('/') || spez.startsWith('#'))
|
|
17
|
+
return undefined;
|
|
18
|
+
const ohnePraefix = spez.startsWith('node:') ? spez.slice(5) : spez;
|
|
19
|
+
if (EINGEBAUT.has(ohnePraefix))
|
|
20
|
+
return undefined;
|
|
21
|
+
const teile = ohnePraefix.split('/');
|
|
22
|
+
return ohnePraefix.startsWith('@') ? teile.slice(0, 2).join('/') : teile[0];
|
|
23
|
+
}
|
|
24
|
+
export function lies(p) {
|
|
25
|
+
try {
|
|
26
|
+
return fs.readFileSync(p, 'utf8');
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function quelltext(wurzel) {
|
|
33
|
+
const teile = [];
|
|
34
|
+
const lauf = (dir, tiefe) => {
|
|
35
|
+
if (tiefe > 8)
|
|
36
|
+
return;
|
|
37
|
+
let eintraege;
|
|
38
|
+
try {
|
|
39
|
+
eintraege = fs.readdirSync(dir, { withFileTypes: true });
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
for (const e of eintraege) {
|
|
45
|
+
if (e.name === 'node_modules' || e.name.startsWith('.'))
|
|
46
|
+
continue;
|
|
47
|
+
const abs = path.join(dir, e.name);
|
|
48
|
+
if (e.isDirectory())
|
|
49
|
+
lauf(abs, tiefe + 1);
|
|
50
|
+
else if (/\.(ts|tsx|js|mjs)$/.test(e.name))
|
|
51
|
+
teile.push(lies(abs) ?? '');
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
lauf(path.join(wurzel, 'src'), 0);
|
|
55
|
+
return teile.join('\n');
|
|
56
|
+
}
|
|
57
|
+
function liestUmgebungsWert(src, name) {
|
|
58
|
+
if (!/process\.env/.test(src))
|
|
59
|
+
return false;
|
|
60
|
+
return (new RegExp(`process\\.env\\.${name}\\b`).test(src) ||
|
|
61
|
+
new RegExp(`process\\.env\\[\\s*['"\`]${name}['"\`]`).test(src) ||
|
|
62
|
+
new RegExp(`['"\`]${name}['"\`]`).test(src));
|
|
63
|
+
}
|
|
64
|
+
export function serverKandidaten(wurzel) {
|
|
65
|
+
let eintraege;
|
|
66
|
+
try {
|
|
67
|
+
eintraege = fs.readdirSync(wurzel, { withFileTypes: true });
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
return eintraege
|
|
73
|
+
.filter((e) => e.isDirectory() && e.name !== 'node_modules' && !e.name.startsWith('.'))
|
|
74
|
+
.filter((e) => fs.existsSync(path.join(wurzel, e.name, 'package.json')) &&
|
|
75
|
+
fs.existsSync(path.join(wurzel, e.name, 'src')))
|
|
76
|
+
.map((e) => e.name);
|
|
77
|
+
}
|
|
78
|
+
function workspaceVerweise(deps) {
|
|
79
|
+
if (!deps)
|
|
80
|
+
return [];
|
|
81
|
+
return Object.entries(deps)
|
|
82
|
+
.filter(([, v]) => v === '*' || v.startsWith('workspace:') || v.startsWith('file:') || v.startsWith('link:'))
|
|
83
|
+
.map(([k]) => k);
|
|
84
|
+
}
|
|
85
|
+
export function pruefeVertrag(wurzel) {
|
|
86
|
+
const befunde = [];
|
|
87
|
+
const gehalten = [];
|
|
88
|
+
const halten = (regel, ok, b, schwere = 'vertrag') => {
|
|
89
|
+
if (ok)
|
|
90
|
+
gehalten.push(regel);
|
|
91
|
+
else
|
|
92
|
+
befunde.push({ regel, schwere, ...b });
|
|
93
|
+
};
|
|
94
|
+
const pkgText = lies(path.join(wurzel, 'package.json'));
|
|
95
|
+
if (!pkgText) {
|
|
96
|
+
return {
|
|
97
|
+
projekt: wurzel,
|
|
98
|
+
gehalten: [],
|
|
99
|
+
befunde: [
|
|
100
|
+
{
|
|
101
|
+
regel: 'arkven/projekt-gefunden',
|
|
102
|
+
schwere: 'ungeprueft',
|
|
103
|
+
titel: 'In diesem Verzeichnis liegt keine package.json, deshalb liess sich nichts messen.',
|
|
104
|
+
ort: 'package.json',
|
|
105
|
+
ausweg: 'Wechsle in das Wurzelverzeichnis deines Projekts und rufe `arkven check` dort erneut auf.',
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
let pkg;
|
|
111
|
+
try {
|
|
112
|
+
pkg = JSON.parse(pkgText);
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
return {
|
|
116
|
+
projekt: wurzel,
|
|
117
|
+
gehalten: [],
|
|
118
|
+
befunde: [
|
|
119
|
+
{
|
|
120
|
+
regel: 'arkven/projekt-gefunden',
|
|
121
|
+
schwere: 'ungeprueft',
|
|
122
|
+
titel: `Die package.json liess sich nicht lesen: ${String(e?.message ?? e)}`,
|
|
123
|
+
ort: 'package.json',
|
|
124
|
+
ausweg: 'Prüfe die Datei auf einen JSON-Fehler (häufig ein Komma zu viel) und rufe `arkven check` erneut auf.',
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
const deps = pkg.dependencies ?? {};
|
|
130
|
+
const hatEigenesSrc = fs.existsSync(path.join(wurzel, 'src'));
|
|
131
|
+
const kandidaten = serverKandidaten(wurzel);
|
|
132
|
+
if (pkg.workspaces || (!hatEigenesSrc && kandidaten.length > 0)) {
|
|
133
|
+
const wohin = kandidaten.length > 0
|
|
134
|
+
? `Dein Server sieht nach ${kandidaten.map((k) => `\`${k}/\``).join(' oder ')} aus. Prüfe ihn direkt: \`arkven check ${kandidaten[0]}\`.`
|
|
135
|
+
: 'Bestimme das Paket, das die App werden soll, und prüfe dieses Verzeichnis direkt.';
|
|
136
|
+
return {
|
|
137
|
+
projekt: wurzel,
|
|
138
|
+
gehalten: [],
|
|
139
|
+
befunde: [
|
|
140
|
+
{
|
|
141
|
+
regel: 'arkven/ein-paket',
|
|
142
|
+
schwere: 'vertrag',
|
|
143
|
+
titel: 'Hier liegt ein Verbund aus mehreren Paketen. Der Container installiert nur im Wurzelverzeichnis, deshalb wird genau ein Paket zur App.',
|
|
144
|
+
ort: 'package.json',
|
|
145
|
+
ausweg: wohin,
|
|
146
|
+
verweis: true,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
regel: 'arkven/vertrag-offen',
|
|
150
|
+
schwere: 'ungeprueft',
|
|
151
|
+
titel: 'Die übrigen Punkte des Container-Vertrags liessen sich hier nicht messen, solange nicht feststeht, welches Paket die App wird.',
|
|
152
|
+
ausweg: 'Rufe `arkven check` auf dem Paket auf, das live gehen soll. Dann werden alle Punkte gemessen.',
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
const src = quelltext(wurzel);
|
|
158
|
+
halten('arkven/einstieg', fs.existsSync(path.join(wurzel, 'src', 'index.ts')), {
|
|
159
|
+
titel: 'Der Container startet `src/index.ts`. Diese Datei fehlt, also hat die App keinen Einstiegspunkt.',
|
|
160
|
+
ort: 'src/index.ts',
|
|
161
|
+
ausweg: 'Lege deinen Serverstart als `src/index.ts` an, oder verschiebe den vorhandenen Einstieg dorthin.',
|
|
162
|
+
});
|
|
163
|
+
if (hatEigenesSrc) {
|
|
164
|
+
halten('arkven/port-aus-umgebung', liestUmgebungsWert(src, 'PORT'), {
|
|
165
|
+
titel: 'Arkven gibt den Port über die Umgebung vor. Ein fest verdrahteter Port ist von außen nicht erreichbar.',
|
|
166
|
+
ort: 'src/',
|
|
167
|
+
ausweg: 'Nimm den Port aus `process.env.PORT` und benutze einen eigenen Wert nur als Rückfall für lokale Läufe.',
|
|
168
|
+
});
|
|
169
|
+
halten('arkven/datenbank-aus-umgebung', liestUmgebungsWert(src, 'DATABASE_URL'), {
|
|
170
|
+
titel: 'Arkven stellt genau eine Datenbank-Verbindung über `DATABASE_URL` bereit. Die App liest sie nicht.',
|
|
171
|
+
ort: 'src/',
|
|
172
|
+
ausweg: 'Verbinde dich über `process.env.DATABASE_URL` statt über einzelne Host- und Passwort-Werte.',
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
for (const [regel, was] of [
|
|
177
|
+
['arkven/port-aus-umgebung', 'ihren Port'],
|
|
178
|
+
['arkven/datenbank-aus-umgebung', 'ihre Datenbank-Verbindung'],
|
|
179
|
+
]) {
|
|
180
|
+
befunde.push({
|
|
181
|
+
regel,
|
|
182
|
+
schwere: 'ungeprueft',
|
|
183
|
+
titel: `In diesem Verzeichnis gibt es kein \`src/\`, deshalb liess sich nicht messen, woher die App ${was} nimmt.`,
|
|
184
|
+
ort: 'src/',
|
|
185
|
+
ausweg: 'Lege den Quelltext unter `src/` ab, oder rufe `arkven check` auf dem Verzeichnis auf, in dem er liegt.',
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const verweise = [...workspaceVerweise(pkg.dependencies), ...workspaceVerweise(pkg.devDependencies)];
|
|
190
|
+
halten('arkven/keine-workspaces', !pkg.workspaces && verweise.length === 0, {
|
|
191
|
+
titel: verweise.length > 0
|
|
192
|
+
? `Diese Abhaengigkeit(en) zeigen auf ein Workspace-Paket und lösen im Container nicht auf: ${verweise.join(', ')}.`
|
|
193
|
+
: 'Diese package.json erklärt Workspaces. Im Container läuft `npm install` nur im Wurzelverzeichnis.',
|
|
194
|
+
ort: 'package.json',
|
|
195
|
+
ausweg: 'Loese die geteilten Pakete auf: den Quelltext ins Projekt übernehmen und die Importe auf relative Pfade umstellen.',
|
|
196
|
+
});
|
|
197
|
+
for (const werkzeug of ['tsx', 'drizzle-kit']) {
|
|
198
|
+
const inDeps = Boolean(deps[werkzeug]);
|
|
199
|
+
const nurDev = !inDeps && Boolean(pkg.devDependencies?.[werkzeug]);
|
|
200
|
+
halten(`arkven/laufzeit-${werkzeug}`, inDeps, {
|
|
201
|
+
titel: nurDev
|
|
202
|
+
? `\`${werkzeug}\` steht unter devDependencies. Der Container installiert nur dependencies, deshalb fehlt es beim Start.`
|
|
203
|
+
: `Der Container ruft \`${werkzeug}\` beim Start. Es steht nicht in den dependencies.`,
|
|
204
|
+
ort: 'package.json',
|
|
205
|
+
ausweg: `\`npm install --save ${werkzeug}\` ausführen, damit es zur Laufzeit vorhanden ist.`,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
if (hatEigenesSrc) {
|
|
209
|
+
const fehlend = new Set();
|
|
210
|
+
const nurDev = new Set();
|
|
211
|
+
const code = nurCode(src);
|
|
212
|
+
for (const re of [IMPORT_RE, IMPORT_DYN_RE, IMPORT_REQUIRE_RE]) {
|
|
213
|
+
for (const treffer of code.matchAll(re)) {
|
|
214
|
+
const name = paketName(treffer[1] ?? '');
|
|
215
|
+
if (!name || deps[name])
|
|
216
|
+
continue;
|
|
217
|
+
if (pkg.devDependencies?.[name])
|
|
218
|
+
nurDev.add(name);
|
|
219
|
+
else
|
|
220
|
+
fehlend.add(name);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const saetze = [];
|
|
224
|
+
const wege = [];
|
|
225
|
+
if (fehlend.size > 0) {
|
|
226
|
+
saetze.push(`Diese Importe zeigen auf Pakete, die im Container nicht existieren: ${[...fehlend].join(', ')}.`);
|
|
227
|
+
wege.push('Trage sie in `dependencies` ein. Zeigt ein Import auf ein Paket aus deinem eigenen Verbund, übernimm dessen Quelltext ins Projekt und stelle den Import auf einen relativen Pfad um.');
|
|
228
|
+
}
|
|
229
|
+
if (nurDev.size > 0) {
|
|
230
|
+
saetze.push(`Diese Pakete stehen unter devDependencies und fehlen deshalb zur Laufzeit: ${[...nurDev].join(', ')}.`);
|
|
231
|
+
wege.push(`\`npm install --save ${[...nurDev].join(' ')}\` ausführen.`);
|
|
232
|
+
}
|
|
233
|
+
halten('arkven/importe-aufloesbar', saetze.length === 0, {
|
|
234
|
+
titel: saetze.join(' '),
|
|
235
|
+
ort: 'src/',
|
|
236
|
+
ausweg: wege.join(' '),
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
halten('arkven/schema-waechter', fs.existsSync(path.join(wurzel, 'src', 'schemaGate.ts')), {
|
|
240
|
+
titel: 'Der Container ruft nach der Migration `src/schemaGate.ts`. Diese Datei prüft, ob das Schema wirklich so aussieht, wie die App es erwartet.',
|
|
241
|
+
ort: 'src/schemaGate.ts',
|
|
242
|
+
ausweg: 'Lege `src/schemaGate.ts` an: sie prüft die erwarteten Tabellen gegen die laufende Datenbank und bricht mit einer klaren Meldung ab, wenn etwas fehlt.',
|
|
243
|
+
});
|
|
244
|
+
const hatSql = fs.existsSync(path.join(wurzel, 'drizzle')) &&
|
|
245
|
+
fs.readdirSync(path.join(wurzel, 'drizzle')).some((f) => f.endsWith('.sql'));
|
|
246
|
+
if (hatSql) {
|
|
247
|
+
halten('arkven/migrations-journal', fs.existsSync(path.join(wurzel, 'drizzle', 'meta', '_journal.json')), {
|
|
248
|
+
titel: 'Es liegen eigene SQL-Dateien vor, aber kein Migrations-Journal. Ohne Journal legt der Container das Schema neu an, statt deine Migrationen zu fahren - Policies, Trigger und Constraints entstehen dabei nicht.',
|
|
249
|
+
ort: 'drizzle/meta/_journal.json',
|
|
250
|
+
ausweg: 'Erzeuge das Journal mit `npx drizzle-kit generate`, damit deine SQL-Dateien in der richtigen Reihenfolge laufen.',
|
|
251
|
+
}, 'hinweis');
|
|
252
|
+
}
|
|
253
|
+
halten('arkven/paketbezug', Object.keys(deps).some((d) => d.startsWith('@arkvenai/')), {
|
|
254
|
+
titel: 'Diese App bezieht keine Arkven-Bausteine als Pakete. Ein Sicherheitsfix an einem Baustein erreicht sie deshalb nicht über eine Aktualisierung.',
|
|
255
|
+
ort: 'package.json',
|
|
256
|
+
ausweg: 'Optional. Wenn du Bausteine nutzen willst: `arkven login`, danach `npm install @arkvenai/base`.',
|
|
257
|
+
}, 'hinweis');
|
|
258
|
+
pruefeSpaeteFallen(wurzel, halten);
|
|
259
|
+
befunde.push({
|
|
260
|
+
regel: 'arkven/plattform-gates',
|
|
261
|
+
schwere: 'ungeprueft',
|
|
262
|
+
titel: 'Die Gates der Plattform (roher SQL, Sicherheits-Header, ausgehende Aufrufe, Struktur) und die Verhaltens-Proben laufen in dieser Fassung noch nicht mit.',
|
|
263
|
+
ausweg: 'Sie laufen beim Veröffentlichen und melden dort mit Datei und Ausweg. Ab einer späteren Fassung dieses Programms laufen sie auch hier.',
|
|
264
|
+
});
|
|
265
|
+
return { projekt: wurzel, gehalten, befunde };
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=vertrag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vertrag.js","sourceRoot":"","sources":["../src/vertrag.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Befund } from './befund.js';
|
|
2
|
+
export type Halten = (regel: string, ok: boolean, b: Omit<Befund, 'regel' | 'schwere'>, schwere?: Befund['schwere']) => void;
|
|
3
|
+
export declare function pruefeSpaeteFallen(wurzel: string, halten: Halten): void;
|
|
4
|
+
//# sourceMappingURL=vertragSpaet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vertragSpaet.d.ts","sourceRoot":"","sources":["../src/vertragSpaet.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,MAAM,MAAM,MAAM,GAAG,CACnB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,OAAO,EACX,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC,EACpC,OAAO,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,KACxB,IAAI,CAAA;AA4KT,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAMvE"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { lies } from './vertrag.js';
|
|
4
|
+
function dateienUnter(wurzel, unter, endungen, tiefe = 6) {
|
|
5
|
+
const treffer = [];
|
|
6
|
+
const lauf = (dir, rest) => {
|
|
7
|
+
if (rest < 0)
|
|
8
|
+
return;
|
|
9
|
+
let eintraege;
|
|
10
|
+
try {
|
|
11
|
+
eintraege = fs.readdirSync(dir, { withFileTypes: true });
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
for (const e of eintraege) {
|
|
17
|
+
if (e.name.startsWith('.') || e.name === 'node_modules')
|
|
18
|
+
continue;
|
|
19
|
+
const p = path.join(dir, e.name);
|
|
20
|
+
if (e.isDirectory())
|
|
21
|
+
lauf(p, rest - 1);
|
|
22
|
+
else if (endungen.some((x) => e.name.endsWith(x)))
|
|
23
|
+
treffer.push(p);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
lauf(path.join(wurzel, unter), tiefe);
|
|
27
|
+
return treffer;
|
|
28
|
+
}
|
|
29
|
+
function quelltext(wurzel) {
|
|
30
|
+
return dateienUnter(wurzel, 'src', ['.ts', '.js', '.mts', '.cts'])
|
|
31
|
+
.map((p) => lies(p) ?? '')
|
|
32
|
+
.join('\n');
|
|
33
|
+
}
|
|
34
|
+
function pruefeSchemaGate(wurzel, halten) {
|
|
35
|
+
const gate = lies(path.join(wurzel, 'src', 'schemaGate.ts'));
|
|
36
|
+
if (!gate)
|
|
37
|
+
return;
|
|
38
|
+
const sql = dateienUnter(wurzel, 'drizzle', ['.sql'])
|
|
39
|
+
.map((p) => lies(p) ?? '')
|
|
40
|
+
.join('\n');
|
|
41
|
+
if (!sql)
|
|
42
|
+
return;
|
|
43
|
+
const angelegt = new Set();
|
|
44
|
+
for (const m of sql.matchAll(/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:[a-z_]+\.)?"?([a-z0-9_]+)"?/gi)) {
|
|
45
|
+
if (m[1])
|
|
46
|
+
angelegt.add(m[1].toLowerCase());
|
|
47
|
+
}
|
|
48
|
+
const verlangt = new Set();
|
|
49
|
+
for (const m of gate.matchAll(/name:\s*'([a-z0-9_]+)'/g)) {
|
|
50
|
+
if (m[1])
|
|
51
|
+
verlangt.add(m[1].toLowerCase());
|
|
52
|
+
}
|
|
53
|
+
for (const m of gate.matchAll(/to_regclass\(\s*'(?:[a-z_]+\.)?([a-z0-9_]+)'/gi)) {
|
|
54
|
+
if (m[1])
|
|
55
|
+
verlangt.add(m[1].toLowerCase());
|
|
56
|
+
}
|
|
57
|
+
const fehlend = [...verlangt].filter((t) => !angelegt.has(t));
|
|
58
|
+
halten('arkven/schemagate-tabellen', fehlend.length === 0, {
|
|
59
|
+
titel: fehlend.length === 1
|
|
60
|
+
? 'Dein Schema-Wächter verlangt die Tabelle "' +
|
|
61
|
+
(fehlend[0] ?? '') +
|
|
62
|
+
'", aber keine Migration legt sie an. Der Container startet damit nicht.'
|
|
63
|
+
: 'Dein Schema-Wächter verlangt ' +
|
|
64
|
+
fehlend.length +
|
|
65
|
+
' Tabellen, die keine Migration anlegt (' +
|
|
66
|
+
fehlend.slice(0, 4).join(', ') +
|
|
67
|
+
'). Der Container startet damit nicht.',
|
|
68
|
+
ort: 'src/schemaGate.ts',
|
|
69
|
+
ausweg: 'Gleiche die Namen mit deinen Migrationen ab (grep "^CREATE TABLE" drizzle/*.sql). Ein Waechter, der eine Tabelle verlangt, die es nie gab, meldet keinen Defekt - er ist einer.',
|
|
70
|
+
});
|
|
71
|
+
const alleHerkuenfte = [];
|
|
72
|
+
const falscheHerkunft = [];
|
|
73
|
+
for (const m of gate.matchAll(/woher:\s*'([0-9a-z_]+)'/g)) {
|
|
74
|
+
const tag = m[1] ?? '';
|
|
75
|
+
if (!tag)
|
|
76
|
+
continue;
|
|
77
|
+
alleHerkuenfte.push(tag);
|
|
78
|
+
if (!fs.existsSync(path.join(wurzel, 'drizzle', tag + '.sql')))
|
|
79
|
+
falscheHerkunft.push(tag);
|
|
80
|
+
}
|
|
81
|
+
if (alleHerkuenfte.length > 0) {
|
|
82
|
+
halten('arkven/schemagate-herkunft', falscheHerkunft.length === 0, {
|
|
83
|
+
titel: falscheHerkunft.length +
|
|
84
|
+
' Herkunfts-Angabe(n) im Schema-Wächter zeigen auf Migrationsdateien, die es nicht gibt (z. B. ' +
|
|
85
|
+
(falscheHerkunft[0] ?? '') +
|
|
86
|
+
'.sql).',
|
|
87
|
+
ort: 'src/schemaGate.ts',
|
|
88
|
+
ausweg: 'Trage die echten Dateinamen aus drizzle/ ein. Eine falsche Angabe bricht nichts, führt aber jede Fehlersuche in die falsche Datei.',
|
|
89
|
+
}, 'hinweis');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function pruefeHealthReady(wurzel, halten) {
|
|
93
|
+
const src = quelltext(wurzel);
|
|
94
|
+
if (!src)
|
|
95
|
+
return;
|
|
96
|
+
const hat = (pfad) => new RegExp('[\'"`]' + pfad + '[\'"`]').test(src);
|
|
97
|
+
const fehlend = ['/health', '/ready'].filter((p) => !hat(p));
|
|
98
|
+
halten('arkven/health-ready', fehlend.length === 0, {
|
|
99
|
+
titel: fehlend.length === 2
|
|
100
|
+
? 'Dein Server hat weder /health noch /ready. Arkven wartet beim Umschalten bis zu 240 Sekunden auf beide und bricht danach ab, auch wenn die App läuft.'
|
|
101
|
+
: 'Deinem Server fehlt ' + (fehlend[0] ?? '') + '. Arkven wartet beim Umschalten darauf und bricht ohne Antwort ab.',
|
|
102
|
+
ort: 'src/',
|
|
103
|
+
ausweg: 'Lege beide an der Wurzel an: /health antwortet immer 200 (lebt der Prozess?), /ready prüft die Datenbank und antwortet 503, wenn sie fehlt. Beide VOR ein Rate-Limit hängen - sonst sperrt die Bereitschaftsprüfung sich selbst aus.',
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function pruefeSuchpfad(wurzel, halten) {
|
|
107
|
+
const src = quelltext(wurzel);
|
|
108
|
+
if (!src || !/SET\s+ROLE/i.test(src))
|
|
109
|
+
return;
|
|
110
|
+
halten('arkven/search-path', /search_path/i.test(src), {
|
|
111
|
+
titel: 'Dein Code wechselt per SET ROLE die Datenbank-Rolle, setzt aber nirgends den Suchpfad. Im Container zeigt der Standard-Suchpfad auf den Namen der Verbindungsrolle - nach dem Wechsel findet er die Tabellen nicht mehr.',
|
|
112
|
+
ort: 'src/',
|
|
113
|
+
ausweg: 'Setze den Suchpfad ausdrücklich bei jeder neuen Verbindung, z. B. SET search_path TO app, public. Ein Suchpfad, der vom Namen der Verbindungsrolle abhängt, ist kein Pfad, sondern ein Zufall.',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
function pruefeFrontendOrt(wurzel, halten) {
|
|
117
|
+
const src = quelltext(wurzel);
|
|
118
|
+
if (!src || !/express\.static|sendFile|serveStatic/.test(src))
|
|
119
|
+
return;
|
|
120
|
+
halten('arkven/frontend-ort', /['"`]public['"`]|\/public\b/.test(src), {
|
|
121
|
+
titel: 'Dein Server liefert statische Dateien aus, kennt aber das Verzeichnis public nicht. Arkven legt das gebaute Frontend genau dort ab.',
|
|
122
|
+
ort: 'src/',
|
|
123
|
+
ausweg: 'Liefere aus <server>/public aus, wenn dort ein Build liegt (z. B. als zweiter Ort neben deinem eigenen). Sonst läuft die API und jede Seite antwortet mit 404.',
|
|
124
|
+
}, 'hinweis');
|
|
125
|
+
}
|
|
126
|
+
const NAMENS_PAARE = [
|
|
127
|
+
{ deins: 'STRIPE_SECRET_KEY', arkven: 'STRIPE_SECRET', was: 'Zahlungen' },
|
|
128
|
+
{ deins: 'STRIPE_API_KEY', arkven: 'STRIPE_SECRET', was: 'Zahlungen' },
|
|
129
|
+
{ deins: 'GOOGLE_MAPS_KEY', arkven: 'GOOGLE_MAPS_API_KEY', was: 'Karten' },
|
|
130
|
+
{ deins: 'SESSION_SECRET', arkven: 'JWT_SECRET', was: 'Signierschlüssel' },
|
|
131
|
+
{ deins: 'AUTH_SECRET', arkven: 'JWT_SECRET', was: 'Signierschlüssel' },
|
|
132
|
+
];
|
|
133
|
+
function pruefeInjizierteNamen(wurzel, halten) {
|
|
134
|
+
const src = quelltext(wurzel);
|
|
135
|
+
if (!src)
|
|
136
|
+
return;
|
|
137
|
+
for (const paar of NAMENS_PAARE) {
|
|
138
|
+
if (!new RegExp('\\b' + paar.deins + '\\b').test(src))
|
|
139
|
+
continue;
|
|
140
|
+
halten('arkven/name-' + paar.arkven.toLowerCase().replace(/_/g, '-'), new RegExp('\\b' + paar.arkven + '\\b').test(src), {
|
|
141
|
+
titel: 'Du liest ' + paar.deins + '; Arkven setzt ' + paar.arkven + ' (' + paar.was + ').',
|
|
142
|
+
ort: 'src/',
|
|
143
|
+
ausweg: 'Lies beide, damit es hier wie dort läuft: process.env.' +
|
|
144
|
+
paar.deins +
|
|
145
|
+
' ?? process.env.' +
|
|
146
|
+
paar.arkven +
|
|
147
|
+
'.',
|
|
148
|
+
}, 'hinweis');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
export function pruefeSpaeteFallen(wurzel, halten) {
|
|
152
|
+
pruefeSchemaGate(wurzel, halten);
|
|
153
|
+
pruefeHealthReady(wurzel, halten);
|
|
154
|
+
pruefeSuchpfad(wurzel, halten);
|
|
155
|
+
pruefeFrontendOrt(wurzel, halten);
|
|
156
|
+
pruefeInjizierteNamen(wurzel, halten);
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=vertragSpaet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vertragSpaet.js","sourceRoot":"","sources":["../src/vertragSpaet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vorlagen.d.ts","sourceRoot":"","sources":["../src/vorlagen.ts"],"names":[],"mappings":"AACA,wBAAgB,qBAAqB,CAAC,GAAG,EAAE;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAgF9F;AAED,eAAO,MAAM,mBAAmB,QAA+D,CAAA;AAE/F,eAAO,MAAM,mBAAmB,UAAqC,CAAA"}
|
package/dist/vorlagen.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export function schemaWaechterVorlage(opt) {
|
|
2
|
+
const gefuellt = opt.tabellen.length > 0;
|
|
3
|
+
const absatz = gefuellt
|
|
4
|
+
? ` * DIE LISTE UNTEN DECKT DIE MITGELIEFERTE MIGRATION AB. Kommt eine Tabelle dazu, ohne die
|
|
5
|
+
* deine App nicht arbeiten kann, gehoert sie hier hinein - je eine pro Fachbereich,
|
|
6
|
+
* nicht die Vollliste. Eine Vollliste muesste bei jeder Migration nachgezogen werden
|
|
7
|
+
* und waere binnen Wochen unvollstaendig, ohne dass es jemand merkt.`
|
|
8
|
+
: ` * DIESE VORLAGE IST NOCH NICHT FERTIG. Trage unten die Tabellen ein, ohne die deine
|
|
9
|
+
* App nicht arbeiten kann - je eine pro Fachbereich, nicht die Vollliste. Solange
|
|
10
|
+
* die Liste leer ist, bricht dieser Waechter ab: einer, der nichts prueft und
|
|
11
|
+
* trotzdem 0 zurueckgibt, ist schlimmer als keiner.`;
|
|
12
|
+
const listenKommentar = gefuellt
|
|
13
|
+
? `/** Je Fachbereich eine, nicht die Vollliste. Schema und Name, wie in der Migration. */`
|
|
14
|
+
: `/** Beispiele: 'public.users', 'app.bookings'. Je Fachbereich eine. */`;
|
|
15
|
+
const liste = gefuellt ? `[${opt.tabellen.map((t) => `'${t}'`).join(', ')}]` : '[]';
|
|
16
|
+
return `/**
|
|
17
|
+
* schemaGate - der Waechter, den der Arkven-Container nach dem Migrieren aufruft
|
|
18
|
+
* ('tsx src/schemaGate.ts'). Ein Rueckgabewert ungleich 0 bricht den Start ab,
|
|
19
|
+
* bevor eine tote App live geht.
|
|
20
|
+
*
|
|
21
|
+
* WARUM ES IHN GIBT: Eine Migration kann mit Rueckgabewert 0 enden, ohne dass das
|
|
22
|
+
* Schema wirklich angelegt ist - eine haengende Fremdschluessel-Referenz reicht.
|
|
23
|
+
* Die App startet dann, antwortet auf jede Abfrage mit einem Fehler und sieht von
|
|
24
|
+
* aussen aus wie ein gelungener Deploy.
|
|
25
|
+
*
|
|
26
|
+
${absatz}
|
|
27
|
+
*
|
|
28
|
+
* Angelegt von 'arkven ${opt.angelegtVon}'. Nachmessen mit 'arkven check'.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import pg from 'pg'
|
|
32
|
+
|
|
33
|
+
${listenKommentar}
|
|
34
|
+
const PFLICHT_TABELLEN: string[] = ${liste}
|
|
35
|
+
|
|
36
|
+
async function main(): Promise<void> {
|
|
37
|
+
if (PFLICHT_TABELLEN.length === 0) {
|
|
38
|
+
console.error('schemaGate: es ist noch keine Pflicht-Tabelle eingetragen.')
|
|
39
|
+
console.error(' So kommst du weiter: trage in src/schemaGate.ts die Tabellen ein, ohne die')
|
|
40
|
+
console.error(' deine App nicht arbeiten kann. Danach: arkven check')
|
|
41
|
+
process.exit(3)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const url = process.env.DATABASE_URL
|
|
45
|
+
if (!url) {
|
|
46
|
+
console.error('schemaGate: DATABASE_URL fehlt, damit ist nichts prüfbar (fail-closed).')
|
|
47
|
+
process.exit(3)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const client = new pg.Client({ connectionString: url, connectionTimeoutMillis: 10000 })
|
|
51
|
+
const fehlend: string[] = []
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
await client.connect()
|
|
55
|
+
for (const name of PFLICHT_TABELLEN) {
|
|
56
|
+
const res = await client.query<{ da: boolean }>('SELECT to_regclass($1) IS NOT NULL AS da', [name])
|
|
57
|
+
if (!res.rows[0]?.da) fehlend.push(name)
|
|
58
|
+
}
|
|
59
|
+
} catch (err) {
|
|
60
|
+
console.error('schemaGate: Prüfung nicht durchführbar:', err instanceof Error ? err.message : err)
|
|
61
|
+
console.error(' Das ist KEIN Freispruch. Der Start wird abgebrochen (fail-closed).')
|
|
62
|
+
process.exit(3)
|
|
63
|
+
} finally {
|
|
64
|
+
await client.end().catch(() => {})
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (fehlend.length > 0) {
|
|
68
|
+
console.error('schemaGate: das Schema ist nicht vollständig angelegt.')
|
|
69
|
+
for (const t of fehlend) console.error(' - ' + t + ' fehlt')
|
|
70
|
+
console.error(' Häufigste Ursache: die Migrationen sind nicht gelaufen (fehlendes')
|
|
71
|
+
console.error(' drizzle/meta/_journal.json). Server-Start abgebrochen.')
|
|
72
|
+
process.exit(3)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.log('schemaGate: ' + PFLICHT_TABELLEN.length + ' Pflicht-Tabelle(n) vorhanden.')
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
void main()
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
export const VORLAGE_SCHEMA_GATE = schemaWaechterVorlage({ tabellen: [], angelegtVon: 'init' });
|
|
82
|
+
export const GITIGNORE_EINTRAEGE = ['node_modules/', 'dist/', '.env'];
|
|
83
|
+
//# sourceMappingURL=vorlagen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vorlagen.js","sourceRoot":"","sources":["../src/vorlagen.ts"],"names":[],"mappings":"AACA,MAAM,UAAU,qBAAqB,CAAC,GAAgD;IACpF,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA;IACxC,MAAM,MAAM,GAAG,QAAQ;QACrB,CAAC,CAAC;;;sEAGgE;QAClE,CAAC,CAAC;;;qDAG+C,CAAA;IACnD,MAAM,eAAe,GAAG,QAAQ;QAC9B,CAAC,CAAC,yFAAyF;QAC3F,CAAC,CAAC,wEAAwE,CAAA;IAC5E,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;IAEnF,OAAO;;;;;;;;;;EAUP,MAAM;;0BAEkB,GAAG,CAAC,WAAW;;;;;EAKvC,eAAe;qCACoB,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CzC,CAAA;AACD,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAA;AAE/F,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,eAAe,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA"}
|