@cogenta/cli 0.3.0 → 0.6.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 +3856 -0
- package/dist/admin-assets/assets/index-CxZHGwVA.css +1 -0
- package/dist/admin-assets/assets/index-fYXyHpn8.js +1090 -0
- package/dist/admin-assets/assets/vips-_dmTUXFO.wasm +0 -0
- package/dist/admin-assets/assets/vips-es6-DrQTTS8Q.js +7 -0
- package/dist/admin-assets/branding/logo-cogenta-dark.png +0 -0
- package/dist/admin-assets/branding/logo-cogenta-icon.png +0 -0
- package/dist/admin-assets/branding/logo-cogenta-light.png +0 -0
- package/dist/admin-assets/branding/logo-cogenta-small.png +0 -0
- package/dist/admin-assets/branding/logo-cogenta-transparent.png +0 -0
- package/dist/admin-assets/branding/logo-cogenta.png +0 -0
- package/dist/admin-assets/favicon.png +0 -0
- package/dist/admin-assets/fonts/ibm-plex-mono-400.woff2 +0 -0
- package/dist/admin-assets/fonts/ibm-plex-mono-500.woff2 +0 -0
- package/dist/admin-assets/fonts/ibm-plex-mono-600.woff2 +0 -0
- package/dist/admin-assets/fonts/ibm-plex-mono-700.woff2 +0 -0
- package/dist/admin-assets/fonts/ibm-plex-sans-var.woff2 +0 -0
- package/dist/admin-assets/fonts/jetbrains-mono-var.woff2 +0 -0
- package/dist/admin-assets/fonts/space-grotesk-var.woff2 +0 -0
- package/dist/admin-assets/index.html +3 -2
- package/dist/bin.js +6 -0
- package/dist/bin.js.map +1 -1
- package/dist/commands/admin-assets.d.ts +1 -0
- package/dist/commands/admin-assets.d.ts.map +1 -1
- package/dist/commands/admin-assets.js +19 -1
- package/dist/commands/admin-assets.js.map +1 -1
- package/dist/commands/agent-runtime.d.ts +151 -0
- package/dist/commands/agent-runtime.d.ts.map +1 -0
- package/dist/commands/agent-runtime.js +519 -0
- package/dist/commands/agent-runtime.js.map +1 -0
- package/dist/commands/assistant.d.ts +89 -3
- package/dist/commands/assistant.d.ts.map +1 -1
- package/dist/commands/assistant.js +206 -39
- package/dist/commands/assistant.js.map +1 -1
- package/dist/commands/audit-integrity-alert.d.ts +23 -0
- package/dist/commands/audit-integrity-alert.d.ts.map +1 -0
- package/dist/commands/audit-integrity-alert.js +33 -0
- package/dist/commands/audit-integrity-alert.js.map +1 -0
- package/dist/commands/backup.d.ts +78 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +238 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/channels.d.ts +47 -0
- package/dist/commands/channels.d.ts.map +1 -0
- package/dist/commands/channels.js +277 -0
- package/dist/commands/channels.js.map +1 -0
- package/dist/commands/default-logo.d.ts +27 -0
- package/dist/commands/default-logo.d.ts.map +1 -0
- package/dist/commands/default-logo.js +30 -0
- package/dist/commands/default-logo.js.map +1 -0
- package/dist/commands/doctor.d.ts +5 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +74 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/export.d.ts +22 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +182 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/forms-page.d.ts +75 -0
- package/dist/commands/forms-page.d.ts.map +1 -0
- package/dist/commands/forms-page.js +191 -0
- package/dist/commands/forms-page.js.map +1 -0
- package/dist/commands/import.d.ts.map +1 -1
- package/dist/commands/import.js +13 -1
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/mcp.d.ts +35 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +277 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/roles.d.ts +22 -0
- package/dist/commands/roles.d.ts.map +1 -0
- package/dist/commands/roles.js +79 -0
- package/dist/commands/roles.js.map +1 -0
- package/dist/commands/search-page.d.ts +15 -0
- package/dist/commands/search-page.d.ts.map +1 -1
- package/dist/commands/search-page.js +22 -16
- package/dist/commands/search-page.js.map +1 -1
- package/dist/commands/seo.d.ts +92 -4
- package/dist/commands/seo.d.ts.map +1 -1
- package/dist/commands/seo.js +168 -4
- package/dist/commands/seo.js.map +1 -1
- package/dist/commands/serve.d.ts +489 -6
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +3883 -164
- package/dist/commands/serve.js.map +1 -1
- package/dist/commands/site-plan.d.ts +27 -1
- package/dist/commands/site-plan.d.ts.map +1 -1
- package/dist/commands/site-plan.js +71 -4
- package/dist/commands/site-plan.js.map +1 -1
- package/dist/commands/term-archive-page.d.ts +94 -0
- package/dist/commands/term-archive-page.d.ts.map +1 -0
- package/dist/commands/term-archive-page.js +195 -0
- package/dist/commands/term-archive-page.js.map +1 -0
- package/dist/commands/theme-css.d.ts +22 -7
- package/dist/commands/theme-css.d.ts.map +1 -1
- package/dist/commands/theme-css.js +33 -8
- package/dist/commands/theme-css.js.map +1 -1
- package/dist/commands/theme-registry.d.ts +94 -0
- package/dist/commands/theme-registry.d.ts.map +1 -0
- package/dist/commands/theme-registry.js +130 -0
- package/dist/commands/theme-registry.js.map +1 -0
- package/dist/commands/theme-render.d.ts +360 -2
- package/dist/commands/theme-render.d.ts.map +1 -1
- package/dist/commands/theme-render.js +984 -29
- package/dist/commands/theme-render.js.map +1 -1
- package/dist/commands/theme-wiring.d.ts +107 -0
- package/dist/commands/theme-wiring.d.ts.map +1 -0
- package/dist/commands/theme-wiring.js +295 -0
- package/dist/commands/theme-wiring.js.map +1 -0
- package/dist/commands/tools.d.ts +71 -0
- package/dist/commands/tools.d.ts.map +1 -0
- package/dist/commands/tools.js +330 -0
- package/dist/commands/tools.js.map +1 -0
- package/dist/commands/update.d.ts +25 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +193 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/users.d.ts.map +1 -1
- package/dist/commands/users.js +6 -36
- package/dist/commands/users.js.map +1 -1
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +146 -4
- package/dist/index.js.map +1 -1
- package/dist/invite-mail.d.ts +39 -0
- package/dist/invite-mail.d.ts.map +1 -0
- package/dist/invite-mail.js +39 -0
- package/dist/invite-mail.js.map +1 -0
- package/dist/reset-mail.d.ts +39 -0
- package/dist/reset-mail.d.ts.map +1 -0
- package/dist/reset-mail.js +45 -0
- package/dist/reset-mail.js.map +1 -0
- package/dist/update/apply.d.ts +54 -0
- package/dist/update/apply.d.ts.map +1 -0
- package/dist/update/apply.js +77 -0
- package/dist/update/apply.js.map +1 -0
- package/dist/update/changelog-risk.d.ts +20 -0
- package/dist/update/changelog-risk.d.ts.map +1 -0
- package/dist/update/changelog-risk.js +55 -0
- package/dist/update/changelog-risk.js.map +1 -0
- package/dist/update/check.d.ts +60 -0
- package/dist/update/check.d.ts.map +1 -0
- package/dist/update/check.js +56 -0
- package/dist/update/check.js.map +1 -0
- package/dist/update/contract-risk.d.ts +55 -0
- package/dist/update/contract-risk.d.ts.map +1 -0
- package/dist/update/contract-risk.js +75 -0
- package/dist/update/contract-risk.js.map +1 -0
- package/dist/update/history.d.ts +30 -0
- package/dist/update/history.d.ts.map +1 -0
- package/dist/update/history.js +38 -0
- package/dist/update/history.js.map +1 -0
- package/dist/update/index.d.ts +28 -0
- package/dist/update/index.d.ts.map +1 -0
- package/dist/update/index.js +11 -0
- package/dist/update/index.js.map +1 -0
- package/dist/update/list-restore-points.d.ts +20 -0
- package/dist/update/list-restore-points.d.ts.map +1 -0
- package/dist/update/list-restore-points.js +35 -0
- package/dist/update/list-restore-points.js.map +1 -0
- package/dist/update/npm-registry.d.ts +11 -0
- package/dist/update/npm-registry.d.ts.map +1 -0
- package/dist/update/npm-registry.js +74 -0
- package/dist/update/npm-registry.js.map +1 -0
- package/dist/update/restore-point.d.ts +26 -0
- package/dist/update/restore-point.d.ts.map +1 -0
- package/dist/update/restore-point.js +23 -0
- package/dist/update/restore-point.js.map +1 -0
- package/dist/update/tar.d.ts +27 -0
- package/dist/update/tar.d.ts.map +1 -0
- package/dist/update/tar.js +56 -0
- package/dist/update/tar.js.map +1 -0
- package/dist/update/version-compare.d.ts +17 -0
- package/dist/update/version-compare.d.ts.map +1 -0
- package/dist/update/version-compare.js +42 -0
- package/dist/update/version-compare.js.map +1 -0
- package/dist/version.d.ts +13 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +18 -0
- package/dist/version.js.map +1 -0
- package/package.json +33 -13
- package/dist/admin-assets/assets/index-Buwdj1V2.js +0 -71
- package/dist/admin-assets/assets/index-Csef0SiA.css +0 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type Logger } from '@cogenta/core';
|
|
2
|
+
import { type PackageUpdateStatus, type UpdateCheckReport } from './check.js';
|
|
3
|
+
import { type UpdateRestorePoint } from './restore-point.js';
|
|
4
|
+
export interface RunPackageInstallInput {
|
|
5
|
+
readonly cwd: string;
|
|
6
|
+
/** `@cogenta/core@0.5.0`-shaped specs — one target version per package, pinned exactly (`--save-exact`). */
|
|
7
|
+
readonly specs: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
export interface RunPackageInstallResult {
|
|
10
|
+
readonly stdout: string;
|
|
11
|
+
readonly stderr: string;
|
|
12
|
+
}
|
|
13
|
+
export type RunPackageInstall = (input: RunPackageInstallInput) => Promise<RunPackageInstallResult>;
|
|
14
|
+
/** Real `npm install --save-exact <specs>`, run in the site's own directory. */
|
|
15
|
+
export declare const runNpmInstall: RunPackageInstall;
|
|
16
|
+
export type ApplyUpdateResult = {
|
|
17
|
+
readonly kind: 'up-to-date';
|
|
18
|
+
readonly report: UpdateCheckReport;
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: 'confirmation-required';
|
|
21
|
+
readonly report: UpdateCheckReport;
|
|
22
|
+
readonly risky: readonly PackageUpdateStatus[];
|
|
23
|
+
} | {
|
|
24
|
+
readonly kind: 'applied';
|
|
25
|
+
readonly report: UpdateCheckReport;
|
|
26
|
+
readonly restorePoint: UpdateRestorePoint;
|
|
27
|
+
readonly installed: readonly {
|
|
28
|
+
readonly name: string;
|
|
29
|
+
readonly version: string;
|
|
30
|
+
}[];
|
|
31
|
+
readonly installOutput: RunPackageInstallResult;
|
|
32
|
+
};
|
|
33
|
+
export interface ApplyUpdateInput {
|
|
34
|
+
readonly cwd?: string;
|
|
35
|
+
readonly env?: Record<string, string | undefined>;
|
|
36
|
+
readonly logger?: Logger;
|
|
37
|
+
readonly packages: readonly {
|
|
38
|
+
readonly name: string;
|
|
39
|
+
readonly installed: string;
|
|
40
|
+
}[];
|
|
41
|
+
/**
|
|
42
|
+
* Required once `check()` has flagged a contract-risk warning for any
|
|
43
|
+
* package in scope — the human-in-the-loop half of point 4 ("proposer
|
|
44
|
+
* d'annuler"). Absent or `false` with a warning present refuses before
|
|
45
|
+
* touching anything, `kind: 'confirmation-required'`.
|
|
46
|
+
*/
|
|
47
|
+
readonly confirmBreakingChange?: boolean;
|
|
48
|
+
readonly fetchImpl?: typeof fetch;
|
|
49
|
+
readonly now?: () => Date;
|
|
50
|
+
readonly backupDir?: string;
|
|
51
|
+
readonly runInstall?: RunPackageInstall;
|
|
52
|
+
}
|
|
53
|
+
export declare function applyUpdate(input: ApplyUpdateInput): Promise<ApplyUpdateResult>;
|
|
54
|
+
//# sourceMappingURL=apply.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/update/apply.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,eAAe,CAAA;AACzD,OAAO,EAAmB,KAAK,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC9F,OAAO,EAA4B,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAoBtF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,4GAA4G;IAC5G,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,sBAAsB,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAA;AAInG,gFAAgF;AAChF,eAAO,MAAM,aAAa,EAAE,iBAkB3B,CAAA;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,GACnE;IACE,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAA;IACtC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAA;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAC/C,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAA;IAClC,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAA;IACzC,QAAQ,CAAC,SAAS,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAClF,QAAQ,CAAC,aAAa,EAAE,uBAAuB,CAAA;CAChD,CAAA;AAEL,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IACjD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACnF;;;;;OAKG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAA;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,iBAAiB,CAAA;CACxC;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAsCrF"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import process from 'node:process';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
import { CogentaError } from '@cogenta/core';
|
|
5
|
+
import { checkForUpdates } from './check.js';
|
|
6
|
+
import { createUpdateRestorePoint } from './restore-point.js';
|
|
7
|
+
/**
|
|
8
|
+
* "Mise à jour en un clic depuis l'admin (ou `cogenta update` en CLI) — avec
|
|
9
|
+
* un point de restauration obligatoire avant toute mise à jour... jamais une
|
|
10
|
+
* mise à jour sans filet" (L22 task 9, point 2).
|
|
11
|
+
*
|
|
12
|
+
* The order is deliberate: a package whose update the caller has not
|
|
13
|
+
* confirmed yet (because `check()` found a contract-risk warning) is refused
|
|
14
|
+
* with `kind: 'confirmation-required'` **before** anything is backed up or
|
|
15
|
+
* installed — there is nothing to protect yet. Once every risky package is
|
|
16
|
+
* confirmed, the restore point is created unconditionally, and only then
|
|
17
|
+
* does `npm install` run. If the backup step itself fails, this throws
|
|
18
|
+
* (`UPDATE_RESTORE_POINT_FAILED`, from `restore-point.ts`) and nothing is
|
|
19
|
+
* installed — a failed safety net cancels the update, it never becomes a
|
|
20
|
+
* warning that gets ignored.
|
|
21
|
+
*/
|
|
22
|
+
const execFileAsync = promisify(execFile);
|
|
23
|
+
const MAX_INSTALL_OUTPUT_BYTES = 10 * 1024 * 1024;
|
|
24
|
+
/** Real `npm install --save-exact <specs>`, run in the site's own directory. */
|
|
25
|
+
export const runNpmInstall = async ({ cwd, specs }) => {
|
|
26
|
+
const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
27
|
+
try {
|
|
28
|
+
const result = await execFileAsync(npmCommand, ['install', '--save-exact', ...specs], {
|
|
29
|
+
cwd,
|
|
30
|
+
maxBuffer: MAX_INSTALL_OUTPUT_BYTES,
|
|
31
|
+
});
|
|
32
|
+
return { stdout: result.stdout, stderr: result.stderr };
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const withOutput = error;
|
|
36
|
+
throw new CogentaError({
|
|
37
|
+
code: 'UPDATE_APPLY_FAILED',
|
|
38
|
+
message: `npm install failed: ${withOutput.message}`,
|
|
39
|
+
hint: 'The restore point taken just before this was not touched — restore it with "cogenta restore apply" if the site is now in a broken state, or fix the underlying npm error (check network access and the npm registry) and try again.',
|
|
40
|
+
cause: error,
|
|
41
|
+
details: { stdout: withOutput.stdout, stderr: withOutput.stderr },
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
export async function applyUpdate(input) {
|
|
46
|
+
const report = await checkForUpdates({
|
|
47
|
+
packages: input.packages,
|
|
48
|
+
...(input.fetchImpl === undefined ? {} : { fetchImpl: input.fetchImpl }),
|
|
49
|
+
...(input.now === undefined ? {} : { now: input.now }),
|
|
50
|
+
});
|
|
51
|
+
const updatable = report.packages.filter((pkg) => pkg.updateAvailable && pkg.latest !== null);
|
|
52
|
+
if (updatable.length === 0)
|
|
53
|
+
return { kind: 'up-to-date', report };
|
|
54
|
+
const risky = updatable.filter((pkg) => (pkg.contractRisk?.warnings.length ?? 0) > 0);
|
|
55
|
+
if (risky.length > 0 && input.confirmBreakingChange !== true) {
|
|
56
|
+
return { kind: 'confirmation-required', report, risky };
|
|
57
|
+
}
|
|
58
|
+
// The safety net, unconditional, before anything else changes.
|
|
59
|
+
const restorePoint = await createUpdateRestorePoint({
|
|
60
|
+
...(input.cwd === undefined ? {} : { cwd: input.cwd }),
|
|
61
|
+
...(input.env === undefined ? {} : { env: input.env }),
|
|
62
|
+
...(input.logger === undefined ? {} : { logger: input.logger }),
|
|
63
|
+
...(input.backupDir === undefined ? {} : { dir: input.backupDir }),
|
|
64
|
+
});
|
|
65
|
+
const cwd = input.cwd ?? process.cwd();
|
|
66
|
+
const runInstall = input.runInstall ?? runNpmInstall;
|
|
67
|
+
const specs = updatable.map((pkg) => `${pkg.name}@${pkg.latest}`);
|
|
68
|
+
const installOutput = await runInstall({ cwd, specs });
|
|
69
|
+
return {
|
|
70
|
+
kind: 'applied',
|
|
71
|
+
report,
|
|
72
|
+
restorePoint,
|
|
73
|
+
installed: updatable.map((pkg) => ({ name: pkg.name, version: pkg.latest })),
|
|
74
|
+
installOutput,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/update/apply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a Changesets-generated `CHANGELOG.md` into per-version sections, and
|
|
3
|
+
* flags the ones that look like they touch a frozen contract (A/B/C/D/E) —
|
|
4
|
+
* a **heuristic keyword scan of prose**, not a structured signal, and it says
|
|
5
|
+
* so everywhere it is surfaced. See `contract-risk.ts`'s module comment for
|
|
6
|
+
* the honest limits of what this can actually detect.
|
|
7
|
+
*/
|
|
8
|
+
export interface ChangelogSection {
|
|
9
|
+
readonly version: string;
|
|
10
|
+
readonly body: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function splitChangelogSections(markdown: string): readonly ChangelogSection[];
|
|
13
|
+
export interface ContractRiskWarning {
|
|
14
|
+
readonly version: string;
|
|
15
|
+
/** The matched section's own text, trimmed to a readable excerpt — never invented, always a substring of the real changelog. */
|
|
16
|
+
readonly excerpt: string;
|
|
17
|
+
}
|
|
18
|
+
/** The versions in `sections` whose body matches `FROZEN_CONTRACT_PATTERN`. */
|
|
19
|
+
export declare function sectionsMentioningContractRisk(sections: readonly ChangelogSection[]): readonly ContractRiskWarning[];
|
|
20
|
+
//# sourceMappingURL=changelog-risk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changelog-risk.d.ts","sourceRoot":"","sources":["../../src/update/changelog-risk.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAKD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,gBAAgB,EAAE,CAmBpF;AAaD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,gIAAgI;IAChI,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED,+EAA+E;AAC/E,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GACpC,SAAS,mBAAmB,EAAE,CAOhC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a Changesets-generated `CHANGELOG.md` into per-version sections, and
|
|
3
|
+
* flags the ones that look like they touch a frozen contract (A/B/C/D/E) —
|
|
4
|
+
* a **heuristic keyword scan of prose**, not a structured signal, and it says
|
|
5
|
+
* so everywhere it is surfaced. See `contract-risk.ts`'s module comment for
|
|
6
|
+
* the honest limits of what this can actually detect.
|
|
7
|
+
*/
|
|
8
|
+
/** `## 0.5.0` — Changesets' own heading format (`@changesets/changelog-github` and the default changelog both use it). */
|
|
9
|
+
const VERSION_HEADING = /^##\s+(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)\s*$/u;
|
|
10
|
+
export function splitChangelogSections(markdown) {
|
|
11
|
+
const lines = markdown.split(/\r\n|\r|\n/u);
|
|
12
|
+
const sections = [];
|
|
13
|
+
let current = null;
|
|
14
|
+
for (const line of lines) {
|
|
15
|
+
const match = VERSION_HEADING.exec(line);
|
|
16
|
+
if (match?.[1] !== undefined) {
|
|
17
|
+
if (current !== null)
|
|
18
|
+
sections.push({ version: current.version, body: current.lines.join('\n').trim() });
|
|
19
|
+
current = { version: match[1], lines: [] };
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (current !== null)
|
|
23
|
+
current.lines.push(line);
|
|
24
|
+
}
|
|
25
|
+
if (current !== null)
|
|
26
|
+
sections.push({ version: current.version, body: current.lines.join('\n').trim() });
|
|
27
|
+
return sections;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Deliberately broad rather than precise: this is a warning, not a
|
|
31
|
+
* certification, and a missed keyword is worse than a false positive here
|
|
32
|
+
* (a human reviews every flagged version before an update is applied). Covers
|
|
33
|
+
* both languages this codebase's own changesets are written in (English,
|
|
34
|
+
* per AGENTS.md) and the French vocabulary this project's own design docs
|
|
35
|
+
* use for the same idea, in case a changeset note quotes one.
|
|
36
|
+
*/
|
|
37
|
+
const FROZEN_CONTRACT_PATTERN = /\bcontract\s+[a-e]\b|\bcontrat\s+[a-e]\b|schema@\d|tools@\d|blocks?@\d|theme@\d|breaking change|changement cassant|frozen contract|contrat\s+fig[eé]|\badr-\d{4}\b/iu;
|
|
38
|
+
/** The versions in `sections` whose body matches `FROZEN_CONTRACT_PATTERN`. */
|
|
39
|
+
export function sectionsMentioningContractRisk(sections) {
|
|
40
|
+
const warnings = [];
|
|
41
|
+
for (const section of sections) {
|
|
42
|
+
if (!FROZEN_CONTRACT_PATTERN.test(section.body))
|
|
43
|
+
continue;
|
|
44
|
+
warnings.push({ version: section.version, excerpt: excerptOf(section.body) });
|
|
45
|
+
}
|
|
46
|
+
return warnings;
|
|
47
|
+
}
|
|
48
|
+
const MAX_EXCERPT_LENGTH = 400;
|
|
49
|
+
function excerptOf(body) {
|
|
50
|
+
const collapsed = body.replace(/\s+/gu, ' ').trim();
|
|
51
|
+
return collapsed.length > MAX_EXCERPT_LENGTH
|
|
52
|
+
? `${collapsed.slice(0, MAX_EXCERPT_LENGTH)}…`
|
|
53
|
+
: collapsed;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=changelog-risk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changelog-risk.js","sourceRoot":"","sources":["../../src/update/changelog-risk.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,0HAA0H;AAC1H,MAAM,eAAe,GAAG,gDAAgD,CAAA;AAExE,MAAM,UAAU,sBAAsB,CAAC,QAAgB;IACrD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;IAC3C,MAAM,QAAQ,GAAuB,EAAE,CAAA;IACvC,IAAI,OAAO,GAAgD,IAAI,CAAA;IAE/D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACxC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,OAAO,KAAK,IAAI;gBAClB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;YACpF,OAAO,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;YAC1C,SAAQ;QACV,CAAC;QACD,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAChD,CAAC;IACD,IAAI,OAAO,KAAK,IAAI;QAClB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IAEpF,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,uBAAuB,GAC3B,sKAAsK,CAAA;AAQxK,+EAA+E;AAC/E,MAAM,UAAU,8BAA8B,CAC5C,QAAqC;IAErC,MAAM,QAAQ,GAA0B,EAAE,CAAA;IAC1C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,SAAQ;QACzD,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC/E,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,MAAM,kBAAkB,GAAG,GAAG,CAAA;AAE9B,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;IACnD,OAAO,SAAS,CAAC,MAAM,GAAG,kBAAkB;QAC1C,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC,GAAG;QAC9C,CAAC,CAAC,SAAS,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type ContractRiskAssessment } from './contract-risk.js';
|
|
2
|
+
import { type UpdateBump } from './version-compare.js';
|
|
3
|
+
/**
|
|
4
|
+
* `cogenta update check` / `GET /api/updates/status` (L22 task 9, point 1):
|
|
5
|
+
* "compare la version installée à la dernière publiée sur npm —
|
|
6
|
+
* `@cogenta/core` et `@cogenta/cli` sont déjà la source de vérité de
|
|
7
|
+
* version."
|
|
8
|
+
*
|
|
9
|
+
* "Installed" here means each package's own self-reported version
|
|
10
|
+
* (`getCoreVersion`/`getCliVersion`, both lazily computed with
|
|
11
|
+
* `readOwnPackageVersion` in `@cogenta/core` — see that function's own
|
|
12
|
+
* comment for why this is never a top-level constant) — whichever
|
|
13
|
+
* `@cogenta/core`/`@cogenta/cli` this very process actually
|
|
14
|
+
* loaded, not a guess read from `node_modules` by path (which would answer
|
|
15
|
+
* a different, less certain question on a hoisted or symlinked install).
|
|
16
|
+
* Scoped to exactly these two packages, deliberately, not every `@cogenta/*`
|
|
17
|
+
* dependency a site happens to carry (`@cogenta/theme-canonical`, any
|
|
18
|
+
* installed plugin…) — see this module's caller for why.
|
|
19
|
+
*
|
|
20
|
+
* Point 4's contract-risk check ("avant d'appliquer : notifier le risque")
|
|
21
|
+
* runs here too, not only inside `apply.ts` — an admin (or `cogenta update
|
|
22
|
+
* check`) needs to see the risk *before* deciding to confirm, so `check()`
|
|
23
|
+
* already fetches it for every package that actually has an update
|
|
24
|
+
* available (never for one that does not — no reason to download a tarball
|
|
25
|
+
* nobody would apply). `includeContractRisk: false` skips it for a caller
|
|
26
|
+
* that only wants the fast version comparison.
|
|
27
|
+
*/
|
|
28
|
+
export interface PackageUpdateStatus {
|
|
29
|
+
readonly name: string;
|
|
30
|
+
readonly installed: string;
|
|
31
|
+
/** `null` only when the registry check for this specific package failed — never when it simply reports no update. */
|
|
32
|
+
readonly latest: string | null;
|
|
33
|
+
readonly bump: UpdateBump;
|
|
34
|
+
readonly updateAvailable: boolean;
|
|
35
|
+
/** Set only when `latest` is `null`. */
|
|
36
|
+
readonly checkError: string | undefined;
|
|
37
|
+
/** `null` when there is no update to assess, or `includeContractRisk` was `false`. See `contract-risk.ts` for how honestly limited this signal is. */
|
|
38
|
+
readonly contractRisk: ContractRiskAssessment | null;
|
|
39
|
+
}
|
|
40
|
+
export interface UpdateCheckReport {
|
|
41
|
+
readonly checkedAt: string;
|
|
42
|
+
readonly packages: readonly PackageUpdateStatus[];
|
|
43
|
+
readonly updateAvailable: boolean;
|
|
44
|
+
readonly highestBump: UpdateBump;
|
|
45
|
+
/** `true` when any package's `contractRisk` actually found a warning — the one field a "should I click apply" UI decision boils down to. */
|
|
46
|
+
readonly contractRiskDetected: boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface CheckForUpdatesInput {
|
|
49
|
+
/** `{ name, installed }` for each package to check — `check.ts` itself has no opinion on which packages that is; `cogenta update`/`update-router.ts` pass `@cogenta/core`/`@cogenta/cli`. */
|
|
50
|
+
readonly packages: readonly {
|
|
51
|
+
readonly name: string;
|
|
52
|
+
readonly installed: string;
|
|
53
|
+
}[];
|
|
54
|
+
readonly fetchImpl?: typeof fetch;
|
|
55
|
+
readonly now?: () => Date;
|
|
56
|
+
/** Default `true`. `false` skips the tarball fetch/scan entirely — a faster, network-lighter check with no risk signal. */
|
|
57
|
+
readonly includeContractRisk?: boolean;
|
|
58
|
+
}
|
|
59
|
+
export declare function checkForUpdates(input: CheckForUpdatesInput): Promise<UpdateCheckReport>;
|
|
60
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/update/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAEpF,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,qHAAqH;IACrH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;IACjC,wCAAwC;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,sJAAsJ;IACtJ,QAAQ,CAAC,YAAY,EAAE,sBAAsB,GAAG,IAAI,CAAA;CACrD;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,SAAS,mBAAmB,EAAE,CAAA;IACjD,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;IACjC,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAA;IAChC,4IAA4I;IAC5I,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAA;CACvC;AAED,MAAM,WAAW,oBAAoB;IACnC,6LAA6L;IAC7L,QAAQ,CAAC,QAAQ,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACnF,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,2HAA2H;IAC3H,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;CACvC;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA0D7F"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { assessContractRisk } from './contract-risk.js';
|
|
2
|
+
import { fetchNpmPackageSummary } from './npm-registry.js';
|
|
3
|
+
import { classifyBump, higherRiskBump } from './version-compare.js';
|
|
4
|
+
export async function checkForUpdates(input) {
|
|
5
|
+
const now = input.now ?? (() => new Date());
|
|
6
|
+
const fetchImpl = input.fetchImpl ?? fetch;
|
|
7
|
+
const includeContractRisk = input.includeContractRisk ?? true;
|
|
8
|
+
const packages = [];
|
|
9
|
+
for (const { name, installed } of input.packages) {
|
|
10
|
+
try {
|
|
11
|
+
const summary = await fetchNpmPackageSummary(name, fetchImpl);
|
|
12
|
+
const bump = classifyBump(installed, summary.latest);
|
|
13
|
+
const updateAvailable = bump !== 'none' && bump !== 'unknown';
|
|
14
|
+
let contractRisk = null;
|
|
15
|
+
const tarballUrl = summary.tarballUrl[summary.latest];
|
|
16
|
+
if (includeContractRisk && updateAvailable && tarballUrl !== undefined) {
|
|
17
|
+
contractRisk = await assessContractRisk({
|
|
18
|
+
packageName: name,
|
|
19
|
+
fromVersion: installed,
|
|
20
|
+
toVersion: summary.latest,
|
|
21
|
+
tarballUrl,
|
|
22
|
+
fetchImpl,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
packages.push({
|
|
26
|
+
name,
|
|
27
|
+
installed,
|
|
28
|
+
latest: summary.latest,
|
|
29
|
+
bump,
|
|
30
|
+
updateAvailable,
|
|
31
|
+
checkError: undefined,
|
|
32
|
+
contractRisk,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
packages.push({
|
|
37
|
+
name,
|
|
38
|
+
installed,
|
|
39
|
+
latest: null,
|
|
40
|
+
bump: 'unknown',
|
|
41
|
+
updateAvailable: false,
|
|
42
|
+
checkError: error instanceof Error ? error.message : String(error),
|
|
43
|
+
contractRisk: null,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const highestBump = packages.reduce((highest, pkg) => higherRiskBump(highest, pkg.bump === 'unknown' ? 'none' : pkg.bump), 'none');
|
|
48
|
+
return {
|
|
49
|
+
checkedAt: now().toISOString(),
|
|
50
|
+
packages,
|
|
51
|
+
updateAvailable: packages.some((pkg) => pkg.updateAvailable),
|
|
52
|
+
highestBump,
|
|
53
|
+
contractRiskDetected: packages.some((pkg) => (pkg.contractRisk?.warnings.length ?? 0) > 0),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/update/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA+B,MAAM,oBAAoB,CAAA;AACpF,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAmB,MAAM,sBAAsB,CAAA;AA2DpF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAA2B;IAC/D,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,GAAS,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;IACjD,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAA;IAC1C,MAAM,mBAAmB,GAAG,KAAK,CAAC,mBAAmB,IAAI,IAAI,CAAA;IAE7D,MAAM,QAAQ,GAA0B,EAAE,CAAA;IAC1C,KAAK,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;YAC7D,MAAM,IAAI,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;YACpD,MAAM,eAAe,GAAG,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,SAAS,CAAA;YAE7D,IAAI,YAAY,GAAkC,IAAI,CAAA;YACtD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;YACrD,IAAI,mBAAmB,IAAI,eAAe,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBACvE,YAAY,GAAG,MAAM,kBAAkB,CAAC;oBACtC,WAAW,EAAE,IAAI;oBACjB,WAAW,EAAE,SAAS;oBACtB,SAAS,EAAE,OAAO,CAAC,MAAM;oBACzB,UAAU;oBACV,SAAS;iBACV,CAAC,CAAA;YACJ,CAAC;YAED,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI;gBACJ,SAAS;gBACT,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,IAAI;gBACJ,eAAe;gBACf,UAAU,EAAE,SAAS;gBACrB,YAAY;aACb,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI;gBACJ,SAAS;gBACT,MAAM,EAAE,IAAI;gBACZ,IAAI,EAAE,SAAS;gBACf,eAAe,EAAE,KAAK;gBACtB,UAAU,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBAClE,YAAY,EAAE,IAAI;aACnB,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CACjC,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EACrF,MAAM,CACP,CAAA;IAED,OAAO;QACL,SAAS,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE;QAC9B,QAAQ;QACR,eAAe,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC;QAC5D,WAAW;QACX,oBAAoB,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;KAC3F,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { CogentaError } from '@cogenta/core';
|
|
2
|
+
import { type ContractRiskWarning } from './changelog-risk.js';
|
|
3
|
+
/**
|
|
4
|
+
* "Avant d'appliquer : notifier le risque si la mise à jour touche un
|
|
5
|
+
* contrat A/B/C/D/E" (L22 task 9, point 4) — read honestly, this is the
|
|
6
|
+
* hardest, least reliable part of the whole feature, and this module is
|
|
7
|
+
* built to be honest about that rather than to overclaim.
|
|
8
|
+
*
|
|
9
|
+
* **What is actually detectable, and since when.** A changeset's own prose
|
|
10
|
+
* lives in `.changeset/*.md` only until a release consumes it into the
|
|
11
|
+
* publishing package's `CHANGELOG.md` — after that, the `.changeset` file is
|
|
12
|
+
* deleted and `CHANGELOG.md` is the only surviving copy. Nothing about that
|
|
13
|
+
* text is ever sent to npm's registry API itself (no "breaking: true" field
|
|
14
|
+
* exists on a package version there); the only way to read it from an
|
|
15
|
+
* installed site, with no access to this repository's own git history, is to
|
|
16
|
+
* fetch the target version's own **published tarball** and read
|
|
17
|
+
* `CHANGELOG.md` out of it directly — which is exactly what this module does
|
|
18
|
+
* (`tar.ts`'s minimal reader, over `dist.tarball` from the npm registry,
|
|
19
|
+
* never a third-party CDN).
|
|
20
|
+
*
|
|
21
|
+
* **The one honest catch.** Before this task, `@cogenta/core` and
|
|
22
|
+
* `@cogenta/cli`'s `package.json` `"files"` was `["dist"]` — `CHANGELOG.md`
|
|
23
|
+
* was never actually included in the published npm tarball at all (verified
|
|
24
|
+
* with a real `npm pack` during this task). This task adds it to `"files"`
|
|
25
|
+
* for both packages, but that only takes effect for versions published
|
|
26
|
+
* **from now on**. Every version already on npm when this ships (`0.1.x`
|
|
27
|
+
* through `0.4.0` at the time of writing) has no `CHANGELOG.md` in its
|
|
28
|
+
* tarball, so this reports `available: false` for those, honestly, rather
|
|
29
|
+
* than inventing a "no risk found" that would really mean "could not look."
|
|
30
|
+
*
|
|
31
|
+
* **Even once it can read a CHANGELOG.md, this is a keyword scan of prose,
|
|
32
|
+
* not a structured signal** (`changelog-risk.ts`'s `FROZEN_CONTRACT_PATTERN`)
|
|
33
|
+
* — deliberately broad, so it can miss an unusually-worded note and it can
|
|
34
|
+
* also flag one that turns out to be harmless. It is a strong hint an admin
|
|
35
|
+
* reviews before confirming, never a guarantee, and the UI/CLI say so.
|
|
36
|
+
*/
|
|
37
|
+
export interface ContractRiskAssessment {
|
|
38
|
+
readonly packageName: string;
|
|
39
|
+
/** `false` when no CHANGELOG.md could be read for the target version at all — an honest "could not determine," never treated as "no risk." */
|
|
40
|
+
readonly available: boolean;
|
|
41
|
+
readonly reason: string | undefined;
|
|
42
|
+
/** Every version between the installed one (exclusive) and the target (inclusive) whose changelog section this could actually read. */
|
|
43
|
+
readonly scannedVersions: readonly string[];
|
|
44
|
+
readonly warnings: readonly ContractRiskWarning[];
|
|
45
|
+
}
|
|
46
|
+
export interface AssessContractRiskInput {
|
|
47
|
+
readonly packageName: string;
|
|
48
|
+
readonly fromVersion: string;
|
|
49
|
+
readonly toVersion: string;
|
|
50
|
+
readonly tarballUrl: string;
|
|
51
|
+
readonly fetchImpl?: typeof fetch;
|
|
52
|
+
}
|
|
53
|
+
export declare function assessContractRisk(input: AssessContractRiskInput): Promise<ContractRiskAssessment>;
|
|
54
|
+
export declare function contractRiskUnknownError(packageName: string, reason: string): CogentaError;
|
|
55
|
+
//# sourceMappingURL=contract-risk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-risk.d.ts","sourceRoot":"","sources":["../../src/update/contract-risk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,OAAO,EACL,KAAK,mBAAmB,EAGzB,MAAM,qBAAqB,CAAA;AAG5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,8IAA8I;IAC9I,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,uIAAuI;IACvI,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3C,QAAQ,CAAC,QAAQ,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAClD;AAQD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAClC;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,sBAAsB,CAAC,CAmDjC;AAWD,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAO1F"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { CogentaError } from '@cogenta/core';
|
|
2
|
+
import { compareVersions, parseVersion } from '@cogenta/plugins';
|
|
3
|
+
import { sectionsMentioningContractRisk, splitChangelogSections, } from './changelog-risk.js';
|
|
4
|
+
import { findPackageFile, readTarGz } from './tar.js';
|
|
5
|
+
const MAX_TARBALL_BYTES = 20 * 1024 * 1024;
|
|
6
|
+
function unavailable(packageName, reason) {
|
|
7
|
+
return { packageName, available: false, reason, scannedVersions: [], warnings: [] };
|
|
8
|
+
}
|
|
9
|
+
export async function assessContractRisk(input) {
|
|
10
|
+
const { packageName, fromVersion, toVersion, tarballUrl } = input;
|
|
11
|
+
const fetchImpl = input.fetchImpl ?? fetch;
|
|
12
|
+
let response;
|
|
13
|
+
try {
|
|
14
|
+
response = await fetchImpl(tarballUrl, { signal: AbortSignal.timeout(15_000) });
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
return unavailable(packageName, `could not download the package tarball: ${String(error)}`);
|
|
18
|
+
}
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
return unavailable(packageName, `the package tarball responded with HTTP ${response.status}`);
|
|
21
|
+
}
|
|
22
|
+
const contentLength = response.headers.get('content-length');
|
|
23
|
+
if (contentLength !== null && Number(contentLength) > MAX_TARBALL_BYTES) {
|
|
24
|
+
return unavailable(packageName, 'the package tarball is larger than this check accepts');
|
|
25
|
+
}
|
|
26
|
+
let bytes;
|
|
27
|
+
try {
|
|
28
|
+
bytes = await response.arrayBuffer();
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
return unavailable(packageName, `could not read the package tarball: ${String(error)}`);
|
|
32
|
+
}
|
|
33
|
+
if (bytes.byteLength > MAX_TARBALL_BYTES) {
|
|
34
|
+
return unavailable(packageName, 'the package tarball is larger than this check accepts');
|
|
35
|
+
}
|
|
36
|
+
let changelog;
|
|
37
|
+
try {
|
|
38
|
+
const entries = readTarGz(Buffer.from(bytes));
|
|
39
|
+
changelog = findPackageFile(entries, 'CHANGELOG.md');
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
return unavailable(packageName, `could not read the package tarball: ${String(error)}`);
|
|
43
|
+
}
|
|
44
|
+
if (changelog === null) {
|
|
45
|
+
return unavailable(packageName, 'this version carries no CHANGELOG.md in its published tarball');
|
|
46
|
+
}
|
|
47
|
+
const sections = splitChangelogSections(changelog.toString('utf8'));
|
|
48
|
+
const inRange = sections.filter((section) => isInRange(section.version, fromVersion, toVersion));
|
|
49
|
+
const warnings = sectionsMentioningContractRisk(inRange);
|
|
50
|
+
return {
|
|
51
|
+
packageName,
|
|
52
|
+
available: true,
|
|
53
|
+
reason: undefined,
|
|
54
|
+
scannedVersions: inRange.map((section) => section.version),
|
|
55
|
+
warnings,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** `fromVersion < version <= toVersion`, via `@cogenta/plugins`'s own comparator — unparseable versions (a pre-release tag this parser does not understand) are excluded rather than guessed at. */
|
|
59
|
+
function isInRange(version, fromVersion, toVersion) {
|
|
60
|
+
const v = parseVersion(version);
|
|
61
|
+
const from = parseVersion(fromVersion);
|
|
62
|
+
const to = parseVersion(toVersion);
|
|
63
|
+
if (v === null || from === null || to === null)
|
|
64
|
+
return false;
|
|
65
|
+
return compareVersions(v, from) > 0 && compareVersions(v, to) <= 0;
|
|
66
|
+
}
|
|
67
|
+
export function contractRiskUnknownError(packageName, reason) {
|
|
68
|
+
return new CogentaError({
|
|
69
|
+
code: 'UPDATE_CHECK_FAILED',
|
|
70
|
+
message: `Could not determine whether updating "${packageName}" touches a frozen contract: ${reason}`,
|
|
71
|
+
hint: 'Review the target version manually before applying, or retry once network access to registry.npmjs.org is available.',
|
|
72
|
+
details: { packageName, reason },
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=contract-risk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-risk.js","sourceRoot":"","sources":["../../src/update/contract-risk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { AuditEntry, AuditLog } from '@cogenta/auth';
|
|
2
|
+
/**
|
|
3
|
+
* "Historique des mises à jour et des points de restauration, consultable
|
|
4
|
+
* depuis le même écran" (L22 task 9, point 5).
|
|
5
|
+
*
|
|
6
|
+
* Never a new table: an update check/apply is one more kind of entry in the
|
|
7
|
+
* audit log every other administrative action already writes to — same
|
|
8
|
+
* pattern `scheduled_task.run` uses in `serve.ts`. The *restore point* half
|
|
9
|
+
* of the history is not duplicated here either — it is exactly `cogenta
|
|
10
|
+
* backup list`'s own answer (`@cogenta/export`'s `readBackupManifest` over
|
|
11
|
+
* the `.cogenta/backups` directory), since `restore-point.ts` writes restore
|
|
12
|
+
* points through the very same `createSiteBackup` function backups already
|
|
13
|
+
* use, just tagged with an `update-` filename prefix. The router/CLI layer
|
|
14
|
+
* that serves "history" to the admin screen combines both reads; this module
|
|
15
|
+
* only owns the audit half.
|
|
16
|
+
*/
|
|
17
|
+
export declare const UPDATE_CHECKED_ACTION = "system.update.checked";
|
|
18
|
+
export declare const UPDATE_APPLIED_ACTION = "system.update.applied";
|
|
19
|
+
export declare const UPDATE_APPLY_FAILED_ACTION = "system.update.apply_failed";
|
|
20
|
+
export interface UpdateHistoryEntryInput {
|
|
21
|
+
readonly actorId: string | null;
|
|
22
|
+
readonly actorRoles: readonly string[];
|
|
23
|
+
readonly action: typeof UPDATE_CHECKED_ACTION | typeof UPDATE_APPLIED_ACTION | typeof UPDATE_APPLY_FAILED_ACTION;
|
|
24
|
+
/** Never a secret, never a full npm install log — package names, versions, bump, restore point path, whether contract risk was flagged. */
|
|
25
|
+
readonly diff: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
export declare function recordUpdateHistory(auditLog: AuditLog, entry: UpdateHistoryEntryInput): Promise<AuditEntry>;
|
|
28
|
+
/** Every update-related audit entry, most recent first — the update-system slice of `AuditLog.list()`. */
|
|
29
|
+
export declare function listUpdateHistory(auditLog: AuditLog, limit?: number): Promise<readonly AuditEntry[]>;
|
|
30
|
+
//# sourceMappingURL=history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/update/history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAEzD;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,qBAAqB,0BAA0B,CAAA;AAC5D,eAAO,MAAM,qBAAqB,0BAA0B,CAAA;AAC5D,eAAO,MAAM,0BAA0B,+BAA+B,CAAA;AAEtE,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,QAAQ,CAAC,MAAM,EACX,OAAO,qBAAqB,GAC5B,OAAO,qBAAqB,GAC5B,OAAO,0BAA0B,CAAA;IACrC,2IAA2I;IAC3I,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACvC;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,UAAU,CAAC,CAOrB;AAED,0GAA0G;AAC1G,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,QAAQ,EAClB,KAAK,SAAK,GACT,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC,CAShC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Historique des mises à jour et des points de restauration, consultable
|
|
3
|
+
* depuis le même écran" (L22 task 9, point 5).
|
|
4
|
+
*
|
|
5
|
+
* Never a new table: an update check/apply is one more kind of entry in the
|
|
6
|
+
* audit log every other administrative action already writes to — same
|
|
7
|
+
* pattern `scheduled_task.run` uses in `serve.ts`. The *restore point* half
|
|
8
|
+
* of the history is not duplicated here either — it is exactly `cogenta
|
|
9
|
+
* backup list`'s own answer (`@cogenta/export`'s `readBackupManifest` over
|
|
10
|
+
* the `.cogenta/backups` directory), since `restore-point.ts` writes restore
|
|
11
|
+
* points through the very same `createSiteBackup` function backups already
|
|
12
|
+
* use, just tagged with an `update-` filename prefix. The router/CLI layer
|
|
13
|
+
* that serves "history" to the admin screen combines both reads; this module
|
|
14
|
+
* only owns the audit half.
|
|
15
|
+
*/
|
|
16
|
+
export const UPDATE_CHECKED_ACTION = 'system.update.checked';
|
|
17
|
+
export const UPDATE_APPLIED_ACTION = 'system.update.applied';
|
|
18
|
+
export const UPDATE_APPLY_FAILED_ACTION = 'system.update.apply_failed';
|
|
19
|
+
export function recordUpdateHistory(auditLog, entry) {
|
|
20
|
+
return auditLog.record({
|
|
21
|
+
actorId: entry.actorId,
|
|
22
|
+
actorRoles: entry.actorRoles,
|
|
23
|
+
action: entry.action,
|
|
24
|
+
diff: entry.diff,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** Every update-related audit entry, most recent first — the update-system slice of `AuditLog.list()`. */
|
|
28
|
+
export async function listUpdateHistory(auditLog, limit = 50) {
|
|
29
|
+
const [checked, applied, failed] = await Promise.all([
|
|
30
|
+
auditLog.list({ action: UPDATE_CHECKED_ACTION, limit }),
|
|
31
|
+
auditLog.list({ action: UPDATE_APPLIED_ACTION, limit }),
|
|
32
|
+
auditLog.list({ action: UPDATE_APPLY_FAILED_ACTION, limit }),
|
|
33
|
+
]);
|
|
34
|
+
return [...checked, ...applied, ...failed]
|
|
35
|
+
.sort((a, b) => (a.at < b.at ? 1 : a.at > b.at ? -1 : 0))
|
|
36
|
+
.slice(0, limit);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/update/history.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAA;AAC5D,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAA;AAC5D,MAAM,CAAC,MAAM,0BAA0B,GAAG,4BAA4B,CAAA;AAatE,MAAM,UAAU,mBAAmB,CACjC,QAAkB,EAClB,KAA8B;IAE9B,OAAO,QAAQ,CAAC,MAAM,CAAC;QACrB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,IAAI,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC,CAAA;AACJ,CAAC;AAED,0GAA0G;AAC1G,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,QAAkB,EAClB,KAAK,GAAG,EAAE;IAEV,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC;QACvD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC;QACvD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,0BAA0B,EAAE,KAAK,EAAE,CAAC;KAC7D,CAAC,CAAA;IACF,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,MAAM,CAAC;SACvC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACxD,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;AACpB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The update system (L22 task 9) — checking npm for a newer
|
|
3
|
+
* `@cogenta/core`/`@cogenta/cli`, applying one with a mandatory restore
|
|
4
|
+
* point first, and the honest, best-effort contract-risk warning that goes
|
|
5
|
+
* with it. See each module's own doc comment for the reasoning; this file
|
|
6
|
+
* is only the barrel.
|
|
7
|
+
*/
|
|
8
|
+
export type { ApplyUpdateInput, ApplyUpdateResult, RunPackageInstall, RunPackageInstallInput, RunPackageInstallResult, } from './apply.js';
|
|
9
|
+
export { applyUpdate, runNpmInstall } from './apply.js';
|
|
10
|
+
export type { ChangelogSection, ContractRiskWarning } from './changelog-risk.js';
|
|
11
|
+
export { sectionsMentioningContractRisk, splitChangelogSections } from './changelog-risk.js';
|
|
12
|
+
export type { CheckForUpdatesInput, PackageUpdateStatus, UpdateCheckReport } from './check.js';
|
|
13
|
+
export { checkForUpdates } from './check.js';
|
|
14
|
+
export type { AssessContractRiskInput, ContractRiskAssessment } from './contract-risk.js';
|
|
15
|
+
export { assessContractRisk, contractRiskUnknownError } from './contract-risk.js';
|
|
16
|
+
export type { UpdateHistoryEntryInput } from './history.js';
|
|
17
|
+
export { listUpdateHistory, recordUpdateHistory, UPDATE_APPLIED_ACTION, UPDATE_APPLY_FAILED_ACTION, UPDATE_CHECKED_ACTION, } from './history.js';
|
|
18
|
+
export type { RestorePointSummary } from './list-restore-points.js';
|
|
19
|
+
export { listRestorePoints } from './list-restore-points.js';
|
|
20
|
+
export type { NpmPackageSummary } from './npm-registry.js';
|
|
21
|
+
export { fetchNpmPackageSummary } from './npm-registry.js';
|
|
22
|
+
export type { CreateUpdateRestorePointOptions, UpdateRestorePoint } from './restore-point.js';
|
|
23
|
+
export { createUpdateRestorePoint } from './restore-point.js';
|
|
24
|
+
export type { TarEntry } from './tar.js';
|
|
25
|
+
export { findPackageFile, readTarEntries, readTarGz } from './tar.js';
|
|
26
|
+
export type { AutoUpdatePolicy, UpdateBump } from './version-compare.js';
|
|
27
|
+
export { AUTO_UPDATE_POLICIES, classifyBump, higherRiskBump, policyAllows, } from './version-compare.js';
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/update/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACvD,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAChF,OAAO,EAAE,8BAA8B,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAC5F,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC9F,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC5C,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AACzF,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AACjF,YAAY,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,YAAY,EAAE,+BAA+B,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAC7F,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAC7D,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACrE,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACxE,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,YAAY,GACb,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { applyUpdate, runNpmInstall } from './apply.js';
|
|
2
|
+
export { sectionsMentioningContractRisk, splitChangelogSections } from './changelog-risk.js';
|
|
3
|
+
export { checkForUpdates } from './check.js';
|
|
4
|
+
export { assessContractRisk, contractRiskUnknownError } from './contract-risk.js';
|
|
5
|
+
export { listUpdateHistory, recordUpdateHistory, UPDATE_APPLIED_ACTION, UPDATE_APPLY_FAILED_ACTION, UPDATE_CHECKED_ACTION, } from './history.js';
|
|
6
|
+
export { listRestorePoints } from './list-restore-points.js';
|
|
7
|
+
export { fetchNpmPackageSummary } from './npm-registry.js';
|
|
8
|
+
export { createUpdateRestorePoint } from './restore-point.js';
|
|
9
|
+
export { findPackageFile, readTarEntries, readTarGz } from './tar.js';
|
|
10
|
+
export { AUTO_UPDATE_POLICIES, classifyBump, higherRiskBump, policyAllows, } from './version-compare.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|