aimeat 1.23.2 → 1.23.3
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/locales/en.json +536 -21
- package/dist/locales/fi.json +548 -33
- package/dist/public/components/ContactCard.js +28 -0
- package/dist/public/css/views/admin.css +12 -0
- package/dist/public/css/views/agents-detail.css +62 -10
- package/dist/public/css/views/landing.css +87 -0
- package/dist/public/css/views/offers.css +96 -0
- package/dist/public/css/views/portfolio.css +18 -0
- package/dist/public/css/views/profile.css +153 -8
- package/dist/public/css/views/start.css +96 -0
- package/dist/public/img/business-hero.png +0 -0
- package/dist/public/img/toimitus.png +0 -0
- package/dist/public/js/components/tag-cloud.js +46 -31
- package/dist/public/js/components/tag-editor.js +2 -2
- package/dist/public/js/recents.js +40 -0
- package/dist/public/js/services/admin.js +6 -0
- package/dist/public/js/services/agents.js +34 -0
- package/dist/public/js/services/offers.js +152 -0
- package/dist/public/js/services/packages.js +1 -0
- package/dist/public/spa.html +32 -2
- package/dist/public/views/admin/subdomains-tab.js +182 -0
- package/dist/public/views/admin.js +2 -0
- package/dist/public/views/business.js +119 -0
- package/dist/public/views/how-it-works.js +159 -0
- package/dist/public/views/landing.js +235 -0
- package/dist/public/views/portfolio.js +120 -23
- package/dist/public/views/pricing.js +75 -0
- package/dist/public/views/profile/access-tab.js +124 -51
- package/dist/public/views/profile/agents/agent-card.js +68 -37
- package/dist/public/views/profile/agents/shared-board.js +56 -22
- package/dist/public/views/profile/agents/tab-activity.js +24 -12
- package/dist/public/views/profile/agents/tab-agent-config.js +31 -1
- package/dist/public/views/profile/agents/tab-data-access.js +9 -13
- package/dist/public/views/profile/agents/tab-integration.js +27 -1
- package/dist/public/views/profile/agents/tab-messages.js +6 -11
- package/dist/public/views/profile/agents/tab-quality.js +45 -5
- package/dist/public/views/profile/agents-tab.js +41 -6
- package/dist/public/views/profile/apps-tab.js +7 -1
- package/dist/public/views/profile/knowledge-tab.js +4 -1
- package/dist/public/views/profile/landing-page.js +427 -123
- package/dist/public/views/profile/memory-tab.js +409 -211
- package/dist/public/views/profile/nodes-tab.js +18 -3
- package/dist/public/views/profile/offers-tab.js +310 -0
- package/dist/public/views/profile/organisms-tab.js +289 -28
- package/dist/public/views/profile/packages-tab.js +152 -16
- package/dist/public/views/profile/portfolio-tab.js +98 -31
- package/dist/public/views/profile.js +2 -0
- package/dist/public/views/start-flows.js +281 -0
- package/dist/public/views/start.js +258 -0
- package/dist/src/generated/api-types.d.ts +856 -17
- package/dist/src/generated/api-types.d.ts.map +1 -1
- package/dist/src/generated/prisma-postgres/edge.js +15 -3
- package/dist/src/generated/prisma-postgres/index-browser.js +12 -0
- package/dist/src/generated/prisma-postgres/index.d.ts +1476 -160
- package/dist/src/generated/prisma-postgres/index.js +15 -3
- package/dist/src/generated/prisma-postgres/package.json +1 -1
- package/dist/src/generated/prisma-postgres/schema.prisma +11 -0
- package/dist/src/generated/prisma-postgres/wasm.js +15 -3
- package/dist/src/middleware/subdomain.d.ts +28 -0
- package/dist/src/middleware/subdomain.d.ts.map +1 -0
- package/dist/src/middleware/subdomain.js +32 -0
- package/dist/src/middleware/subdomain.js.map +1 -0
- package/dist/src/models/offer-schemas.d.ts +229 -0
- package/dist/src/models/offer-schemas.d.ts.map +1 -0
- package/dist/src/models/offer-schemas.js +100 -0
- package/dist/src/models/offer-schemas.js.map +1 -0
- package/dist/src/routes/agent-tasks.d.ts.map +1 -1
- package/dist/src/routes/agent-tasks.js +33 -0
- package/dist/src/routes/agent-tasks.js.map +1 -1
- package/dist/src/routes/agents.d.ts.map +1 -1
- package/dist/src/routes/agents.js +146 -1
- package/dist/src/routes/agents.js.map +1 -1
- package/dist/src/routes/apps-backup.d.ts +20 -0
- package/dist/src/routes/apps-backup.d.ts.map +1 -0
- package/dist/src/routes/apps-backup.js +165 -0
- package/dist/src/routes/apps-backup.js.map +1 -0
- package/dist/src/routes/ghii.d.ts.map +1 -1
- package/dist/src/routes/ghii.js +4 -0
- package/dist/src/routes/ghii.js.map +1 -1
- package/dist/src/routes/instances.d.ts +2 -1
- package/dist/src/routes/instances.d.ts.map +1 -1
- package/dist/src/routes/instances.js +59 -1
- package/dist/src/routes/instances.js.map +1 -1
- package/dist/src/routes/packages.d.ts.map +1 -1
- package/dist/src/routes/packages.js +32 -0
- package/dist/src/routes/packages.js.map +1 -1
- package/dist/src/routes/permissions.d.ts +12 -0
- package/dist/src/routes/permissions.d.ts.map +1 -1
- package/dist/src/routes/permissions.js +35 -3
- package/dist/src/routes/permissions.js.map +1 -1
- package/dist/src/routes/portal.d.ts +3 -0
- package/dist/src/routes/portal.d.ts.map +1 -1
- package/dist/src/routes/portal.js +12 -0
- package/dist/src/routes/portal.js.map +1 -1
- package/dist/src/routes/public-stats.d.ts +15 -0
- package/dist/src/routes/public-stats.d.ts.map +1 -0
- package/dist/src/routes/public-stats.js +90 -0
- package/dist/src/routes/public-stats.js.map +1 -0
- package/dist/src/routes/sse.d.ts +7 -2
- package/dist/src/routes/sse.d.ts.map +1 -1
- package/dist/src/routes/sse.js +35 -5
- package/dist/src/routes/sse.js.map +1 -1
- package/dist/src/routes/subdomains.d.ts +33 -0
- package/dist/src/routes/subdomains.d.ts.map +1 -0
- package/dist/src/routes/subdomains.js +208 -0
- package/dist/src/routes/subdomains.js.map +1 -0
- package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.js +12 -1
- package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
- package/dist/src/server.d.ts.map +1 -1
- package/dist/src/server.js +4 -0
- package/dist/src/server.js.map +1 -1
- package/dist/src/services/apps-backup-export.d.ts +22 -0
- package/dist/src/services/apps-backup-export.d.ts.map +1 -0
- package/dist/src/services/apps-backup-export.js +136 -0
- package/dist/src/services/apps-backup-export.js.map +1 -0
- package/dist/src/services/apps-backup-import.d.ts +120 -0
- package/dist/src/services/apps-backup-import.d.ts.map +1 -0
- package/dist/src/services/apps-backup-import.js +259 -0
- package/dist/src/services/apps-backup-import.js.map +1 -0
- package/dist/src/services/component-registrar.d.ts +17 -0
- package/dist/src/services/component-registrar.d.ts.map +1 -1
- package/dist/src/services/component-registrar.js +63 -5
- package/dist/src/services/component-registrar.js.map +1 -1
- package/dist/src/services/handbooks/appdev.d.ts +1 -1
- package/dist/src/services/handbooks/appdev.d.ts.map +1 -1
- package/dist/src/services/handbooks/appdev.js +5 -2
- package/dist/src/services/handbooks/appdev.js.map +1 -1
- package/dist/src/storage/interface.d.ts +11 -1
- package/dist/src/storage/interface.d.ts.map +1 -1
- package/dist/src/storage/interface.js.map +1 -1
- package/dist/src/storage/providers/mongodb/index.d.ts +10 -1
- package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -1
- package/dist/src/storage/providers/mongodb/index.js +76 -0
- package/dist/src/storage/providers/mongodb/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/index.d.ts +8 -1
- package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/index.js +61 -0
- package/dist/src/storage/providers/sqlite/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.js +11 -0
- package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
- package/dist/src/storage/repositories/index.d.ts +1 -0
- package/dist/src/storage/repositories/index.d.ts.map +1 -1
- package/dist/src/storage/repositories/package.repository.d.ts +2 -0
- package/dist/src/storage/repositories/package.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/subdomain-site.repository.d.ts +19 -0
- package/dist/src/storage/repositories/subdomain-site.repository.d.ts.map +1 -0
- package/dist/src/storage/repositories/subdomain-site.repository.js +2 -0
- package/dist/src/storage/repositories/subdomain-site.repository.js.map +1 -0
- package/dist/static/app-catalog.html +1139 -28
- package/package.json +1 -1
- package/prisma/schema.postgres.prisma +11 -0
- package/prisma/schema.prisma +11 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file apps-backup-export.ts
|
|
3
|
+
* @description Export the owner's whole app catalog as one ZIP: EVERY published
|
|
4
|
+
* app with EVERY stored version (the version history is part of the property),
|
|
5
|
+
* plus the owner's installed cortex extensions (manifest + lib files). Mirrors
|
|
6
|
+
* the organism/workspace export-bundle conventions (archiver, versioned
|
|
7
|
+
* manifest, folder-per-item layout). The backup contains content + metadata
|
|
8
|
+
* only — never access codes, tokens or keys.
|
|
9
|
+
* @structure APPS_BACKUP_VERSION; exportAppsBackup(storage, config, opts)
|
|
10
|
+
* @usage import { exportAppsBackup } from '../services/apps-backup-export.js';
|
|
11
|
+
* @version-history
|
|
12
|
+
* v1.0.0 — 2026-06-12 — Initial: owner app-catalog backup (apps + versions + extensions)
|
|
13
|
+
*/
|
|
14
|
+
import archiver from 'archiver';
|
|
15
|
+
export const APPS_BACKUP_VERSION = '1.0';
|
|
16
|
+
/** Folder/entry name segments must be plain — anything else is skipped, not mangled. */
|
|
17
|
+
const SAFE_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
18
|
+
function versionFileName(v) {
|
|
19
|
+
return `v${v.versionNumber}.${v.mimeType.startsWith('text/html') ? 'html' : 'bin'}`;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Builds the backup ZIP. When `sink` is given (e.g. the HTTP response) the
|
|
23
|
+
* archive is streamed into it as it is built — backups can be large; otherwise
|
|
24
|
+
* the full ZIP is returned as a Buffer.
|
|
25
|
+
*/
|
|
26
|
+
export async function exportAppsBackup(storage, config, opts, sink) {
|
|
27
|
+
const { owner, ownerGhii, exportedAt } = opts;
|
|
28
|
+
const archive = archiver('zip', { zlib: { level: 6 } });
|
|
29
|
+
const chunks = [];
|
|
30
|
+
const done = new Promise((resolve, reject) => {
|
|
31
|
+
archive.on('error', reject);
|
|
32
|
+
if (sink) {
|
|
33
|
+
sink.on('error', reject);
|
|
34
|
+
archive.on('end', () => resolve(Buffer.alloc(0)));
|
|
35
|
+
archive.pipe(sink);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
archive.on('data', (c) => chunks.push(c));
|
|
39
|
+
archive.on('end', () => resolve(Buffer.concat(chunks)));
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
const manifest = {
|
|
43
|
+
aimeatAppsBackup: APPS_BACKUP_VERSION,
|
|
44
|
+
exportedAt,
|
|
45
|
+
source: { nodeId: config.nodeId, owner },
|
|
46
|
+
apps: [],
|
|
47
|
+
extensions: [],
|
|
48
|
+
};
|
|
49
|
+
// Subdomain mappings are included as informational metadata only (they are an
|
|
50
|
+
// operator-managed resource; restore never recreates them).
|
|
51
|
+
const subdomainByTarget = new Map();
|
|
52
|
+
for (const s of await storage.listSubdomainSites()) {
|
|
53
|
+
if (s.kind === 'app')
|
|
54
|
+
subdomainByTarget.set(s.target, { subdomain: s.subdomain, enabled: s.enabled });
|
|
55
|
+
}
|
|
56
|
+
// ── Apps: every app in the owner's canonical bucket, every version ──
|
|
57
|
+
let appCount = 0;
|
|
58
|
+
let versionCount = 0;
|
|
59
|
+
const { apps } = await storage.listApps({ ownerGaii: ownerGhii, limit: 100000 });
|
|
60
|
+
for (const latest of apps) {
|
|
61
|
+
if (!SAFE_SEGMENT.test(latest.filename))
|
|
62
|
+
continue; // publish validation makes this unreachable
|
|
63
|
+
const versions = (await storage.listAppVersions(ownerGhii, latest.filename))
|
|
64
|
+
.sort((a, b) => a.versionNumber - b.versionNumber);
|
|
65
|
+
if (versions.length === 0)
|
|
66
|
+
continue;
|
|
67
|
+
const folder = `apps/${latest.filename}`;
|
|
68
|
+
const versionMeta = [];
|
|
69
|
+
for (const v of versions) {
|
|
70
|
+
const file = versionFileName(v);
|
|
71
|
+
// Prisma (Mongo/Postgres) returns Bytes columns as Uint8Array; archiver
|
|
72
|
+
// accepts only Buffer/string/stream.
|
|
73
|
+
const data = Buffer.isBuffer(v.data) ? v.data : Buffer.from(v.data);
|
|
74
|
+
archive.append(data, { name: `${folder}/versions/${file}` });
|
|
75
|
+
versionMeta.push({
|
|
76
|
+
version: v.versionNumber,
|
|
77
|
+
file: `versions/${file}`,
|
|
78
|
+
mimeType: v.mimeType,
|
|
79
|
+
size: v.size,
|
|
80
|
+
createdAt: v.createdAt,
|
|
81
|
+
manifest: v.manifest,
|
|
82
|
+
});
|
|
83
|
+
versionCount++;
|
|
84
|
+
}
|
|
85
|
+
const appJson = {
|
|
86
|
+
filename: latest.filename,
|
|
87
|
+
name: latest.manifest.name,
|
|
88
|
+
mimeType: latest.mimeType,
|
|
89
|
+
downloads: await storage.getAppDownloads(ownerGhii, latest.filename),
|
|
90
|
+
protected: !!latest.accessCode, // flag only — the code itself is never exported
|
|
91
|
+
subdomain: subdomainByTarget.get(`${owner}/${latest.filename}`) ?? null,
|
|
92
|
+
versions: versionMeta,
|
|
93
|
+
};
|
|
94
|
+
archive.append(JSON.stringify(appJson, null, 2), { name: `${folder}/app.json` });
|
|
95
|
+
manifest.apps.push({
|
|
96
|
+
filename: latest.filename,
|
|
97
|
+
name: latest.manifest.name,
|
|
98
|
+
folder,
|
|
99
|
+
versions: versions.map(v => v.versionNumber),
|
|
100
|
+
});
|
|
101
|
+
appCount++;
|
|
102
|
+
}
|
|
103
|
+
// ── Cortex extensions installed by this owner ──
|
|
104
|
+
let extCount = 0;
|
|
105
|
+
const exts = await storage.listCortexExtensions({ installedBy: owner });
|
|
106
|
+
for (const ext of exts) {
|
|
107
|
+
if (!SAFE_SEGMENT.test(ext.name))
|
|
108
|
+
continue;
|
|
109
|
+
const folder = `extensions/${ext.name}`;
|
|
110
|
+
archive.append(JSON.stringify(ext, null, 2), { name: `${folder}/ext.json` });
|
|
111
|
+
archive.append(ext.manifest ?? '', { name: `${folder}/manifest.yaml` });
|
|
112
|
+
const libNames = ext.activationArtifacts?.libFiles ?? [];
|
|
113
|
+
for (const lib of libNames) {
|
|
114
|
+
if (!SAFE_SEGMENT.test(lib))
|
|
115
|
+
continue;
|
|
116
|
+
const content = await storage.getCortexLibFile(ext.name, lib);
|
|
117
|
+
if (content !== null)
|
|
118
|
+
archive.append(content, { name: `${folder}/libs/${lib}` });
|
|
119
|
+
}
|
|
120
|
+
manifest.extensions.push({ name: ext.name, folder });
|
|
121
|
+
extCount++;
|
|
122
|
+
}
|
|
123
|
+
archive.append(JSON.stringify(manifest, null, 2), { name: 'backup-manifest.json' });
|
|
124
|
+
archive.finalize();
|
|
125
|
+
const buffer = await done;
|
|
126
|
+
const date = exportedAt.slice(0, 10);
|
|
127
|
+
const safeOwner = owner.replace(/[^a-z0-9_-]+/gi, '-').slice(0, 40) || 'owner';
|
|
128
|
+
return {
|
|
129
|
+
buffer,
|
|
130
|
+
filename: `aimeat-apps-${safeOwner}-${date}.zip`,
|
|
131
|
+
apps: appCount,
|
|
132
|
+
versions: versionCount,
|
|
133
|
+
extensions: extCount,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=apps-backup-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apps-backup-export.js","sourceRoot":"","sources":["../../../src/services/apps-backup-export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file apps-backup-import.ts
|
|
3
|
+
* @description Parse, inspect and selectively restore an app-catalog backup ZIP
|
|
4
|
+
* (produced by apps-backup-export). Two-phase UX mirrors the organism import:
|
|
5
|
+
* parse/inspect first WITHOUT writing anything, then restore only the selected
|
|
6
|
+
* apps/versions with an explicit per-app conflict mode — skip (default),
|
|
7
|
+
* append-versions, or import-as-copy. NOTHING is ever silently overwritten.
|
|
8
|
+
* Restore always writes into the CALLER's ownership; the manifest's owner may
|
|
9
|
+
* differ (node-to-node transfer is a use case). All ZIP parsing goes through
|
|
10
|
+
* safeUnzip (zip-slip / zip-bomb / format-allowlist hardening).
|
|
11
|
+
* @structure parseAppsBackup; inspectAppsBackup; restoreAppsBackup; types
|
|
12
|
+
* @usage import { parseAppsBackup, restoreAppsBackup } from '../services/apps-backup-import.js';
|
|
13
|
+
* @version-history
|
|
14
|
+
* v1.0.0 — 2026-06-12 — Initial: selective app-catalog restore with conflict modes
|
|
15
|
+
*/
|
|
16
|
+
import type { Storage, AppManifest, CortexExtensionRecord } from '../storage/interface.js';
|
|
17
|
+
import { type SafeZipLimits } from './safe-zip.js';
|
|
18
|
+
export declare const APPS_BACKUP_ZIP_LIMITS: SafeZipLimits;
|
|
19
|
+
export interface ParsedBackupVersion {
|
|
20
|
+
version: number;
|
|
21
|
+
mimeType: string;
|
|
22
|
+
size: number;
|
|
23
|
+
createdAt: string;
|
|
24
|
+
manifest: AppManifest;
|
|
25
|
+
data: Buffer;
|
|
26
|
+
}
|
|
27
|
+
export interface ParsedBackupApp {
|
|
28
|
+
filename: string;
|
|
29
|
+
name: string;
|
|
30
|
+
versions: ParsedBackupVersion[];
|
|
31
|
+
}
|
|
32
|
+
export interface ParsedBackupExtension {
|
|
33
|
+
record: CortexExtensionRecord;
|
|
34
|
+
libs: Map<string, string>;
|
|
35
|
+
}
|
|
36
|
+
export interface ParsedAppsBackup {
|
|
37
|
+
source: {
|
|
38
|
+
nodeId: string;
|
|
39
|
+
owner: string;
|
|
40
|
+
};
|
|
41
|
+
exportedAt: string;
|
|
42
|
+
apps: ParsedBackupApp[];
|
|
43
|
+
extensions: ParsedBackupExtension[];
|
|
44
|
+
}
|
|
45
|
+
/** Unzip + validate the backup. Throws ZipSecurityError / Error — writes nothing. */
|
|
46
|
+
export declare function parseAppsBackup(zip: Buffer): Promise<ParsedAppsBackup>;
|
|
47
|
+
export interface BackupInspection {
|
|
48
|
+
source: {
|
|
49
|
+
nodeId: string;
|
|
50
|
+
owner: string;
|
|
51
|
+
};
|
|
52
|
+
exported_at: string;
|
|
53
|
+
apps: Array<{
|
|
54
|
+
filename: string;
|
|
55
|
+
name: string;
|
|
56
|
+
exists: boolean;
|
|
57
|
+
existing_versions: number;
|
|
58
|
+
versions: Array<{
|
|
59
|
+
version: number;
|
|
60
|
+
size: number;
|
|
61
|
+
created_at: string;
|
|
62
|
+
semver: string;
|
|
63
|
+
}>;
|
|
64
|
+
}>;
|
|
65
|
+
extensions: Array<{
|
|
66
|
+
name: string;
|
|
67
|
+
exists: boolean;
|
|
68
|
+
}>;
|
|
69
|
+
totals: {
|
|
70
|
+
apps: number;
|
|
71
|
+
versions: number;
|
|
72
|
+
extensions: number;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** Pure read — reports what the backup contains and what would conflict. */
|
|
76
|
+
export declare function inspectAppsBackup(storage: Storage, ownerGhii: string, parsed: ParsedAppsBackup): Promise<BackupInspection>;
|
|
77
|
+
export type AppConflictMode = 'skip' | 'append' | 'copy';
|
|
78
|
+
export type ExtConflictMode = 'skip' | 'copy';
|
|
79
|
+
export interface AppSelection {
|
|
80
|
+
filename: string;
|
|
81
|
+
versions?: number[];
|
|
82
|
+
conflict?: AppConflictMode;
|
|
83
|
+
}
|
|
84
|
+
export interface ExtSelection {
|
|
85
|
+
name: string;
|
|
86
|
+
conflict?: ExtConflictMode;
|
|
87
|
+
}
|
|
88
|
+
export interface RestoreSummary {
|
|
89
|
+
apps_created: string[];
|
|
90
|
+
apps_appended: string[];
|
|
91
|
+
apps_copied: Array<{
|
|
92
|
+
from: string;
|
|
93
|
+
to: string;
|
|
94
|
+
}>;
|
|
95
|
+
apps_skipped: string[];
|
|
96
|
+
versions_restored: number;
|
|
97
|
+
extensions_created: string[];
|
|
98
|
+
extensions_copied: Array<{
|
|
99
|
+
from: string;
|
|
100
|
+
to: string;
|
|
101
|
+
}>;
|
|
102
|
+
extensions_skipped: string[];
|
|
103
|
+
errors: Array<{
|
|
104
|
+
item: string;
|
|
105
|
+
message: string;
|
|
106
|
+
}>;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Restores the selected apps/extensions into the CALLER's account. Conflicts
|
|
110
|
+
* are resolved per item with an explicit mode; the default is skip — an
|
|
111
|
+
* existing app is never touched without an explicit choice.
|
|
112
|
+
*/
|
|
113
|
+
export declare function restoreAppsBackup(storage: Storage, opts: {
|
|
114
|
+
owner: string;
|
|
115
|
+
ownerGhii: string;
|
|
116
|
+
parsed: ParsedAppsBackup;
|
|
117
|
+
selections: AppSelection[];
|
|
118
|
+
extensions?: ExtSelection[];
|
|
119
|
+
}): Promise<RestoreSummary>;
|
|
120
|
+
//# sourceMappingURL=apps-backup-import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apps-backup-import.d.ts","sourceRoot":"","sources":["../../../src/services/apps-backup-import.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { safeUnzip, BACKUP_ZIP_LIMITS } from './safe-zip.js';
|
|
2
|
+
import { APPS_BACKUP_VERSION } from './apps-backup-export.js';
|
|
3
|
+
const APP_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
4
|
+
/** Format allowlist — any entry outside this layout rejects the whole ZIP. */
|
|
5
|
+
function allowName(name) {
|
|
6
|
+
return name === 'backup-manifest.json'
|
|
7
|
+
|| /^apps\/[A-Za-z0-9][A-Za-z0-9._-]*\/app\.json$/.test(name)
|
|
8
|
+
|| /^apps\/[A-Za-z0-9][A-Za-z0-9._-]*\/versions\/v\d+\.(html|bin)$/.test(name)
|
|
9
|
+
|| /^extensions\/[A-Za-z0-9][A-Za-z0-9._-]*\/ext\.json$/.test(name)
|
|
10
|
+
|| /^extensions\/[A-Za-z0-9][A-Za-z0-9._-]*\/manifest\.yaml$/.test(name)
|
|
11
|
+
|| /^extensions\/[A-Za-z0-9][A-Za-z0-9._-]*\/libs\/[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name);
|
|
12
|
+
}
|
|
13
|
+
export const APPS_BACKUP_ZIP_LIMITS = { ...BACKUP_ZIP_LIMITS, allowName };
|
|
14
|
+
/** Unzip + validate the backup. Throws ZipSecurityError / Error — writes nothing. */
|
|
15
|
+
export async function parseAppsBackup(zip) {
|
|
16
|
+
const files = await safeUnzip(zip, APPS_BACKUP_ZIP_LIMITS);
|
|
17
|
+
const manifestBuf = files.get('backup-manifest.json');
|
|
18
|
+
if (!manifestBuf)
|
|
19
|
+
throw new Error('backup-manifest.json missing — not an AIMEAT apps backup');
|
|
20
|
+
const manifest = JSON.parse(manifestBuf.toString('utf8'));
|
|
21
|
+
if (manifest.aimeatAppsBackup !== APPS_BACKUP_VERSION) {
|
|
22
|
+
throw new Error(`Unsupported backup format version (expected ${APPS_BACKUP_VERSION})`);
|
|
23
|
+
}
|
|
24
|
+
const apps = [];
|
|
25
|
+
for (const entry of manifest.apps ?? []) {
|
|
26
|
+
const filename = String(entry.filename ?? '');
|
|
27
|
+
if (!APP_SEGMENT.test(filename))
|
|
28
|
+
throw new Error(`Invalid app filename in manifest: "${filename}"`);
|
|
29
|
+
const folder = `apps/${filename}`;
|
|
30
|
+
const appJsonBuf = files.get(`${folder}/app.json`);
|
|
31
|
+
if (!appJsonBuf)
|
|
32
|
+
throw new Error(`${folder}/app.json missing`);
|
|
33
|
+
const appJson = JSON.parse(appJsonBuf.toString('utf8'));
|
|
34
|
+
const versions = [];
|
|
35
|
+
for (const v of appJson.versions ?? []) {
|
|
36
|
+
const num = Number(v.version);
|
|
37
|
+
if (!Number.isInteger(num) || num < 1)
|
|
38
|
+
throw new Error(`Invalid version number in ${folder}/app.json`);
|
|
39
|
+
const file = String(v.file ?? '');
|
|
40
|
+
if (!/^versions\/v\d+\.(html|bin)$/.test(file))
|
|
41
|
+
throw new Error(`Invalid version file reference in ${folder}/app.json`);
|
|
42
|
+
const data = files.get(`${folder}/${file}`);
|
|
43
|
+
if (!data)
|
|
44
|
+
throw new Error(`${folder}/${file} missing`);
|
|
45
|
+
versions.push({
|
|
46
|
+
version: num,
|
|
47
|
+
mimeType: typeof v.mimeType === 'string' ? v.mimeType : 'text/html',
|
|
48
|
+
size: data.length,
|
|
49
|
+
createdAt: typeof v.createdAt === 'string' ? v.createdAt : new Date().toISOString(),
|
|
50
|
+
manifest: (v.manifest && typeof v.manifest === 'object') ? v.manifest : { name: filename, description: '', version: '1.0.0', category: 'tool', tags: [], authorDisplay: '', usesCortex: [] },
|
|
51
|
+
data,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
versions.sort((a, b) => a.version - b.version);
|
|
55
|
+
if (new Set(versions.map(v => v.version)).size !== versions.length) {
|
|
56
|
+
throw new Error(`Duplicate version numbers for app "${filename}"`);
|
|
57
|
+
}
|
|
58
|
+
apps.push({ filename, name: String(appJson.name ?? filename), versions });
|
|
59
|
+
}
|
|
60
|
+
const extensions = [];
|
|
61
|
+
for (const entry of manifest.extensions ?? []) {
|
|
62
|
+
const name = String(entry.name ?? '');
|
|
63
|
+
if (!APP_SEGMENT.test(name))
|
|
64
|
+
throw new Error(`Invalid extension name in manifest: "${name}"`);
|
|
65
|
+
const folder = `extensions/${name}`;
|
|
66
|
+
const extJsonBuf = files.get(`${folder}/ext.json`);
|
|
67
|
+
if (!extJsonBuf)
|
|
68
|
+
throw new Error(`${folder}/ext.json missing`);
|
|
69
|
+
const record = JSON.parse(extJsonBuf.toString('utf8'));
|
|
70
|
+
if (record.name !== name)
|
|
71
|
+
throw new Error(`Extension name mismatch in ${folder}/ext.json`);
|
|
72
|
+
const libs = new Map();
|
|
73
|
+
for (const [path, buf] of files) {
|
|
74
|
+
const m = path.match(/^extensions\/([A-Za-z0-9][A-Za-z0-9._-]*)\/libs\/([A-Za-z0-9][A-Za-z0-9._-]*)$/);
|
|
75
|
+
if (m && m[1] === name)
|
|
76
|
+
libs.set(m[2], buf.toString('utf8'));
|
|
77
|
+
}
|
|
78
|
+
extensions.push({ record, libs });
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
source: { nodeId: String(manifest.source?.nodeId ?? ''), owner: String(manifest.source?.owner ?? '') },
|
|
82
|
+
exportedAt: String(manifest.exportedAt ?? ''),
|
|
83
|
+
apps,
|
|
84
|
+
extensions,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/** Pure read — reports what the backup contains and what would conflict. */
|
|
88
|
+
export async function inspectAppsBackup(storage, ownerGhii, parsed) {
|
|
89
|
+
const apps = [];
|
|
90
|
+
let versionTotal = 0;
|
|
91
|
+
for (const app of parsed.apps) {
|
|
92
|
+
const latest = await storage.getLatestVersionNumber(ownerGhii, app.filename);
|
|
93
|
+
versionTotal += app.versions.length;
|
|
94
|
+
apps.push({
|
|
95
|
+
filename: app.filename,
|
|
96
|
+
name: app.name,
|
|
97
|
+
exists: latest > 0,
|
|
98
|
+
existing_versions: latest > 0 ? (await storage.listAppVersions(ownerGhii, app.filename)).length : 0,
|
|
99
|
+
versions: app.versions.map(v => ({
|
|
100
|
+
version: v.version, size: v.size, created_at: v.createdAt, semver: v.manifest.version,
|
|
101
|
+
})),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
const extensions = [];
|
|
105
|
+
for (const ext of parsed.extensions) {
|
|
106
|
+
extensions.push({ name: ext.record.name, exists: !!(await storage.getCortexExtension(ext.record.name)) });
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
source: parsed.source,
|
|
110
|
+
exported_at: parsed.exportedAt,
|
|
111
|
+
apps,
|
|
112
|
+
extensions,
|
|
113
|
+
totals: { apps: parsed.apps.length, versions: versionTotal, extensions: parsed.extensions.length },
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/** "name.html" → "name-restored.html" (then -restored-2, -3, … until free). */
|
|
117
|
+
async function uniqueCopyFilename(storage, ownerGhii, filename) {
|
|
118
|
+
const dot = filename.lastIndexOf('.');
|
|
119
|
+
const base = dot > 0 ? filename.slice(0, dot) : filename;
|
|
120
|
+
const ext = dot > 0 ? filename.slice(dot) : '';
|
|
121
|
+
for (let i = 1; i < 100; i++) {
|
|
122
|
+
const candidate = i === 1 ? `${base}-restored${ext}` : `${base}-restored-${i}${ext}`;
|
|
123
|
+
if (await storage.getLatestVersionNumber(ownerGhii, candidate) === 0)
|
|
124
|
+
return candidate;
|
|
125
|
+
}
|
|
126
|
+
throw new Error(`Could not find a free copy name for "${filename}"`);
|
|
127
|
+
}
|
|
128
|
+
async function uniqueCopyExtName(storage, name) {
|
|
129
|
+
for (let i = 1; i < 100; i++) {
|
|
130
|
+
const candidate = i === 1 ? `${name}-restored` : `${name}-restored-${i}`;
|
|
131
|
+
if (!(await storage.getCortexExtension(candidate)))
|
|
132
|
+
return candidate;
|
|
133
|
+
}
|
|
134
|
+
throw new Error(`Could not find a free copy name for extension "${name}"`);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Restores the selected apps/extensions into the CALLER's account. Conflicts
|
|
138
|
+
* are resolved per item with an explicit mode; the default is skip — an
|
|
139
|
+
* existing app is never touched without an explicit choice.
|
|
140
|
+
*/
|
|
141
|
+
export async function restoreAppsBackup(storage, opts) {
|
|
142
|
+
const { owner, ownerGhii, parsed, selections } = opts;
|
|
143
|
+
const summary = {
|
|
144
|
+
apps_created: [], apps_appended: [], apps_copied: [], apps_skipped: [],
|
|
145
|
+
versions_restored: 0,
|
|
146
|
+
extensions_created: [], extensions_copied: [], extensions_skipped: [],
|
|
147
|
+
errors: [],
|
|
148
|
+
};
|
|
149
|
+
const byFilename = new Map(parsed.apps.map(a => [a.filename, a]));
|
|
150
|
+
for (const sel of selections) {
|
|
151
|
+
try {
|
|
152
|
+
const app = byFilename.get(sel.filename);
|
|
153
|
+
if (!app) {
|
|
154
|
+
summary.errors.push({ item: sel.filename, message: 'Not present in the backup' });
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
let versions = app.versions;
|
|
158
|
+
if (sel.versions && sel.versions.length > 0) {
|
|
159
|
+
const wanted = new Set(sel.versions);
|
|
160
|
+
versions = app.versions.filter(v => wanted.has(v.version));
|
|
161
|
+
if (versions.length !== wanted.size) {
|
|
162
|
+
summary.errors.push({ item: sel.filename, message: 'Selection references versions not present in the backup' });
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (versions.length === 0) {
|
|
167
|
+
summary.apps_skipped.push(sel.filename);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const writeVersions = async (filename, renumberFrom) => {
|
|
171
|
+
let next = renumberFrom ?? 0;
|
|
172
|
+
for (const v of versions) {
|
|
173
|
+
const versionNumber = renumberFrom !== undefined ? ++next : v.version;
|
|
174
|
+
await storage.createApp({
|
|
175
|
+
ownerGaii: ownerGhii,
|
|
176
|
+
ownerName: owner,
|
|
177
|
+
filename,
|
|
178
|
+
versionNumber,
|
|
179
|
+
// Ownership transfers to the caller; everything else is preserved.
|
|
180
|
+
manifest: { ...v.manifest, authorDisplay: owner },
|
|
181
|
+
mimeType: v.mimeType,
|
|
182
|
+
size: v.data.length,
|
|
183
|
+
data: v.data,
|
|
184
|
+
createdAt: v.createdAt,
|
|
185
|
+
});
|
|
186
|
+
summary.versions_restored++;
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
const latest = await storage.getLatestVersionNumber(ownerGhii, sel.filename);
|
|
190
|
+
if (latest === 0) {
|
|
191
|
+
await writeVersions(sel.filename); // free name — keep original numbering
|
|
192
|
+
summary.apps_created.push(sel.filename);
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
const mode = sel.conflict ?? 'skip';
|
|
196
|
+
if (mode === 'skip') {
|
|
197
|
+
summary.apps_skipped.push(sel.filename);
|
|
198
|
+
}
|
|
199
|
+
else if (mode === 'append') {
|
|
200
|
+
await writeVersions(sel.filename, latest); // backup versions stack on top
|
|
201
|
+
summary.apps_appended.push(sel.filename);
|
|
202
|
+
}
|
|
203
|
+
else if (mode === 'copy') {
|
|
204
|
+
const copyName = await uniqueCopyFilename(storage, ownerGhii, sel.filename);
|
|
205
|
+
await writeVersions(copyName); // keep original numbering under the new name
|
|
206
|
+
summary.apps_copied.push({ from: sel.filename, to: copyName });
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
summary.errors.push({ item: sel.filename, message: `Unknown conflict mode "${String(mode)}"` });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
catch (e) {
|
|
213
|
+
summary.errors.push({ item: sel.filename, message: e.message });
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const extByName = new Map(parsed.extensions.map(x => [x.record.name, x]));
|
|
217
|
+
for (const sel of opts.extensions ?? []) {
|
|
218
|
+
try {
|
|
219
|
+
const ext = extByName.get(sel.name);
|
|
220
|
+
if (!ext) {
|
|
221
|
+
summary.errors.push({ item: sel.name, message: 'Not present in the backup' });
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const writeExt = async (name) => {
|
|
225
|
+
const record = {
|
|
226
|
+
...ext.record,
|
|
227
|
+
name,
|
|
228
|
+
installedBy: owner,
|
|
229
|
+
// Restored inactive — activation re-derives artifacts in this node's context.
|
|
230
|
+
status: 'inactive',
|
|
231
|
+
activatedAt: undefined,
|
|
232
|
+
installedAt: new Date().toISOString(),
|
|
233
|
+
namespace: ext.record.namespace === parsed.source.owner ? owner : ext.record.namespace,
|
|
234
|
+
};
|
|
235
|
+
await storage.createCortexExtension(record);
|
|
236
|
+
for (const [lib, content] of ext.libs)
|
|
237
|
+
await storage.setCortexLibFile(name, lib, content);
|
|
238
|
+
};
|
|
239
|
+
const exists = !!(await storage.getCortexExtension(sel.name));
|
|
240
|
+
if (!exists) {
|
|
241
|
+
await writeExt(sel.name);
|
|
242
|
+
summary.extensions_created.push(sel.name);
|
|
243
|
+
}
|
|
244
|
+
else if ((sel.conflict ?? 'skip') === 'copy') {
|
|
245
|
+
const copyName = await uniqueCopyExtName(storage, sel.name);
|
|
246
|
+
await writeExt(copyName);
|
|
247
|
+
summary.extensions_copied.push({ from: sel.name, to: copyName });
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
summary.extensions_skipped.push(sel.name);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
catch (e) {
|
|
254
|
+
summary.errors.push({ item: sel.name, message: e.message });
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return summary;
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=apps-backup-import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apps-backup-import.js","sourceRoot":"","sources":["../../../src/services/apps-backup-import.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,6 +26,8 @@ export interface ComponentRegistrationResult {
|
|
|
26
26
|
componentId: string;
|
|
27
27
|
registeredAs: string;
|
|
28
28
|
error?: string;
|
|
29
|
+
/** Short name from the source manifest (only set for cortex + extension). */
|
|
30
|
+
originalShortName?: string;
|
|
29
31
|
}
|
|
30
32
|
export interface ComponentRegistrationInput {
|
|
31
33
|
componentId: string;
|
|
@@ -39,6 +41,21 @@ export interface ComponentRegistrationInput {
|
|
|
39
41
|
packageCategory?: string;
|
|
40
42
|
packageTags?: string[];
|
|
41
43
|
packageDescription?: string;
|
|
44
|
+
/**
|
|
45
|
+
* URL rewrites applied to app HTML content at install time. Built by the
|
|
46
|
+
* installer from already-registered cortex/extension components in the same
|
|
47
|
+
* package. Without this, app HTML containing
|
|
48
|
+
* loadScript('/v1/cortex/comicland-v2/libs/comicland-v2.js')
|
|
49
|
+
* would 404 once the cortex is registered as
|
|
50
|
+
* comicland-v2-alice-06c4c5af-cortex-comicland-v2
|
|
51
|
+
* (the package-install scheme).
|
|
52
|
+
*/
|
|
53
|
+
urlRewrites?: {
|
|
54
|
+
/** Map<originalShortName, registeredAs> for cortex components. */
|
|
55
|
+
cortexNames?: Map<string, string>;
|
|
56
|
+
/** Map<originalShortName, registeredAs> for extension components. */
|
|
57
|
+
extensionNames?: Map<string, string>;
|
|
58
|
+
};
|
|
42
59
|
}
|
|
43
60
|
/** Compute SHA-256 hash of content string */
|
|
44
61
|
export declare function computeHash(content: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-registrar.d.ts","sourceRoot":"","sources":["../../../src/services/component-registrar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAI7E,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"component-registrar.d.ts","sourceRoot":"","sources":["../../../src/services/component-registrar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAI7E,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,oBAAoB,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE;QACZ,kEAAkE;QAClE,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAClC,qEAAqE;QACrE,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACtC,CAAC;CACH;AAID,6CAA6C;AAC7C,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AA6DD,mEAAmE;AACnE,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,2BAA2B,CAAC,CAmTtC;AAID,uEAAuE;AACvE,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,oBAAoB,EAC1B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAiDlB;AAID,yEAAyE;AACzE,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,oBAAoB,EAC1B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyDxB"}
|