From a3febbdd79ae7454ae42bf7e6b1f5234bb14f195 Mon Sep 17 00:00:00 2001 From: Omar Salah Date: Wed, 12 Feb 2025 11:01:03 +0200 Subject: [PATCH] Add dist to repo --- .gitignore | 1 - dist/esm/index.js | 4 + dist/esm/package.json | 3 + dist/index.d.ts | 31 ++++++ dist/index.d.ts.map | 1 + dist/index.js | 227 ++++++++++++++++++++++++++++++++++++++++++ dist/index.js.map | 1 + dist/verify.d.ts | 11 ++ dist/verify.d.ts.map | 1 + dist/verify.js | 115 +++++++++++++++++++++ dist/verify.js.map | 1 + 11 files changed, 395 insertions(+), 1 deletion(-) create mode 100644 dist/esm/index.js create mode 100644 dist/esm/package.json create mode 100644 dist/index.d.ts create mode 100644 dist/index.d.ts.map create mode 100644 dist/index.js create mode 100644 dist/index.js.map create mode 100644 dist/verify.d.ts create mode 100644 dist/verify.d.ts.map create mode 100644 dist/verify.js create mode 100644 dist/verify.js.map diff --git a/.gitignore b/.gitignore index 32accec..2f5ca5d 100644 --- a/.gitignore +++ b/.gitignore @@ -84,7 +84,6 @@ typings/ # Nuxt.js build / generate output .nuxt -dist # Gatsby files .cache/ diff --git a/dist/esm/index.js b/dist/esm/index.js new file mode 100644 index 0000000..301f90a --- /dev/null +++ b/dist/esm/index.js @@ -0,0 +1,4 @@ +import cjsModule from "../index.js"; +export const exportActorProfile = cjsModule.exportActorProfile; +export const importActorProfile = cjsModule.importActorProfile; +export const validateExportStream = cjsModule.validateExportStream; diff --git a/dist/esm/package.json b/dist/esm/package.json new file mode 100644 index 0000000..3dbc1ca --- /dev/null +++ b/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 0000000..e55c530 --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,31 @@ +/*! + * Copyright (c) 2024 Interop Alliance and Dmitri Zagidulin. All rights reserved. + */ +import * as tar from 'tar-stream'; +import { type Readable } from 'stream'; +export interface ActorProfileOptions { + actorProfile?: any; + outbox?: any; + followers?: any; + followingAccounts?: any; + lists?: any; + bookmarks?: any; + likes?: any; + blockedAccounts?: any; + blockedDomains?: any; + mutedAccounts?: any; +} +export declare function exportActorProfile({ actorProfile, outbox, followers, followingAccounts, lists, bookmarks, likes, blockedAccounts, blockedDomains, mutedAccounts }: ActorProfileOptions & { + media?: File[]; +}): Promise<{ + addMediaFile: (fileName: string, buffer: ArrayBuffer, contentType: string) => void; + finalize: () => tar.Pack; +}>; +/** + * Imports an ActivityPub profile from a .tar archive stream. + * @param tarStream - A ReadableStream containing the .tar archive. + * @returns A promise that resolves to the parsed profile data. + */ +export declare function importActorProfile(tarStream: Readable): Promise>; +export * from './verify'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map new file mode 100644 index 0000000..b7feeff --- /dev/null +++ b/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,GAAG,MAAM,YAAY,CAAA;AAGjC,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAGtC,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,GAAG,CAAA;IAClB,MAAM,CAAC,EAAE,GAAG,CAAA;IACZ,SAAS,CAAC,EAAE,GAAG,CAAA;IACf,iBAAiB,CAAC,EAAE,GAAG,CAAA;IACvB,KAAK,CAAC,EAAE,GAAG,CAAA;IACX,SAAS,CAAC,EAAE,GAAG,CAAA;IACf,KAAK,CAAC,EAAE,GAAG,CAAA;IACX,eAAe,CAAC,EAAE,GAAG,CAAA;IACrB,cAAc,CAAC,EAAE,GAAG,CAAA;IACpB,aAAa,CAAC,EAAE,GAAG,CAAA;CACpB;AAED,wBAAsB,kBAAkB,CAAC,EACvC,YAAY,EACZ,MAAM,EACN,SAAS,EACT,iBAAiB,EACjB,KAAK,EACL,SAAS,EACT,KAAK,EACL,eAAe,EACf,cAAc,EACd,aAAa,EACd,EAAE,mBAAmB,GAAG;IAAE,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;CAAE,GAAG,OAAO,CAAC;IACpD,YAAY,EAAE,CACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,MAAM,KAChB,IAAI,CAAA;IACT,QAAQ,EAAE,MAAM,GAAG,CAAC,IAAI,CAAA;CACzB,CAAC,CA2ID;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,QAAQ,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAqE9B;AAyBD,cAAc,UAAU,CAAA"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..38603c0 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,227 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.exportActorProfile = exportActorProfile; +exports.importActorProfile = importActorProfile; +/*! + * Copyright (c) 2024 Interop Alliance and Dmitri Zagidulin. All rights reserved. + */ +const tar = __importStar(require("tar-stream")); +const yaml_1 = __importDefault(require("yaml")); +const path_1 = __importDefault(require("path")); +async function exportActorProfile({ actorProfile, outbox, followers, followingAccounts, lists, bookmarks, likes, blockedAccounts, blockedDomains, mutedAccounts }) { + const pack = tar.pack(); + const manifest = { + 'ubc-version': '0.1', + meta: { + createdBy: { + client: { + url: 'https://github.com/interop-alliance/wallet-export-ts' + } + } + }, + contents: { + 'manifest.yml': { + url: 'https://w3id.org/fep/6fcd#manifest-file' + }, + activitypub: { + contents: {} + }, + media: { + contents: {} + } + } + }; + pack.entry({ name: 'activitypub', type: 'directory' }); + pack.entry({ name: 'media', type: 'directory' }); + if (actorProfile) { + manifest.contents.activitypub.contents['actor.json'] = { + url: 'https://www.w3.org/TR/activitypub/#actor-objects' + }; + pack.entry({ name: 'activitypub/actor.json' }, JSON.stringify(actorProfile, null, 2)); + } + if (outbox) { + manifest.contents.activitypub.contents['outbox.json'] = { + url: 'https://www.w3.org/TR/activitystreams-core/#collections' + }; + pack.entry({ name: 'activitypub/outbox.json' }, JSON.stringify(outbox, null, 2)); + } + if (followers) { + manifest.contents.activitypub.contents['followers.json'] = { + url: 'https://www.w3.org/TR/activitystreams-core/#collections' + }; + pack.entry({ name: 'activitypub/followers.json' }, JSON.stringify(followers, null, 2)); + } + if (likes) { + manifest.contents.activitypub.contents['likes.json'] = { + url: 'https://www.w3.org/TR/activitystreams-core/#collections' + }; + pack.entry({ name: 'activitypub/likes.json' }, JSON.stringify(likes, null, 2)); + } + if (bookmarks) { + manifest.contents.activitypub.contents['bookmarks.json'] = { + url: 'https://www.w3.org/TR/activitystreams-core/#collections' + }; + pack.entry({ name: 'activitypub/bookmarks.json' }, JSON.stringify(bookmarks, null, 2)); + } + if (followingAccounts) { + manifest.contents.activitypub.contents['following.json'] = { + url: 'https://docs.joinmastodon.org/user/moving/#export' + }; + pack.entry({ name: 'activitypub/following.json' }, JSON.stringify(followers, null, 2)); + } + if (lists) { + manifest.contents.activitypub.contents['lists.json'] = { + url: 'https://docs.joinmastodon.org/user/moving/#export' + }; + pack.entry({ name: 'activitypub/lists.json' }, JSON.stringify(lists, null, 2)); + } + if (blockedAccounts) { + manifest.contents.activitypub.contents['blocked_accounts.json'] = { + url: 'https://docs.joinmastodon.org/user/moving/#export' + }; + pack.entry({ name: 'activitypub/blocked_accounts.json' }, JSON.stringify(blockedAccounts, null, 2)); + } + if (blockedDomains) { + manifest.contents.activitypub.contents['blocked_domains.json'] = { + url: 'https://docs.joinmastodon.org/user/moving/#export' + }; + pack.entry({ name: 'activitypub/blocked_domains.csv' }, JSON.stringify(blockedDomains, null, 2)); + } + if (mutedAccounts) { + manifest.contents.activitypub.contents['muted_accounts.json'] = { + url: 'https://docs.joinmastodon.org/user/moving/#export' + }; + pack.entry({ name: 'activitypub/muted_accounts.json' }, JSON.stringify(mutedAccounts, null, 2)); + } + return { + addMediaFile(fileName, buffer, contentType) { + addMediaFile(pack, manifest, fileName, buffer, contentType); + }, + finalize() { + pack.entry({ name: 'manifest.yaml' }, yaml_1.default.stringify(manifest)); + pack.finalize(); + return pack; + } + }; +} +/** + * Imports an ActivityPub profile from a .tar archive stream. + * @param tarStream - A ReadableStream containing the .tar archive. + * @returns A promise that resolves to the parsed profile data. + */ +async function importActorProfile(tarStream) { + console.log('🚀 Starting to process tar stream...'); + const extract = tar.extract(); + const result = {}; + return await new Promise((resolve, reject) => { + extract.on('entry', (header, stream, next) => { + // Normalize fileName to include only `activitypub/filename` + const originalFileName = header.name; + const fileName = `activitypub/${path_1.default.basename(originalFileName)}`; + // Skip system-generated files + if (fileName.startsWith('activitypub/._') || + fileName.endsWith('.DS_Store')) { + console.warn(`Skipping system-generated file: ${fileName}`); + next(); + } + console.log(`Processing file: ${fileName}`); + let content = ''; + stream.on('data', (chunk) => { + content += chunk.toString(); + }); + stream.on('end', () => { + try { + if (fileName.endsWith('.json')) { + result[fileName] = JSON.parse(content); + console.log('Parsed JSON file successfully:', fileName); + } + else if (fileName.endsWith('.yaml') || fileName.endsWith('.yml')) { + result[fileName] = yaml_1.default.parse(content); + } + else if (fileName.endsWith('.csv')) { + result[fileName] = content; + } + else { + console.warn(`Unsupported file type: ${fileName}, skipping...`); + } + } + catch (error) { + console.error(`Error processing file ${fileName}:`, error.message); + } + finally { + next(); // Always continue + } + }); + stream.on('error', (error) => { + console.error(`Stream error on file ${fileName}:`, error.message); + next(); // Continue even on stream error + }); + }); + extract.on('finish', () => { + console.log('All files processed successfully.'); + resolve(result); + }); + extract.on('error', (error) => { + console.error('Error during tar extraction:', error.message); + reject(new Error('Failed to extract tar file.')); + }); + tarStream.on('error', (error) => { + console.error('Error in tar stream:', error.message); + reject(new Error('Failed to process tar stream.')); + }); + tarStream.pipe(extract); + }); +} +function addMediaFile(pack, manifest, fileName, buffer, contentType) { + pack.entry({ + name: `media/${fileName}`, + size: buffer.byteLength + }, Buffer.from(buffer)); + // Add media metadata to the manifest + manifest.contents.media.contents[fileName] = { + type: contentType, + size: buffer.byteLength, + lastModified: new Date().toISOString() + }; +} +__exportStar(require("./verify"), exports); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 0000000..765ed7b --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/verify.d.ts b/dist/verify.d.ts new file mode 100644 index 0000000..12a4796 --- /dev/null +++ b/dist/verify.d.ts @@ -0,0 +1,11 @@ +import { type Readable } from 'stream'; +/** + * Validates the structure and content of an exported ActivityPub tarball. + * @param tarStream - A ReadableStream containing the .tar archive. + * @returns A promise that resolves to an object with `valid` (boolean) and `errors` (string[]). + */ +export declare function validateExportStream(tarStream: Readable): Promise<{ + valid: boolean; + errors: string[]; +}>; +//# sourceMappingURL=verify.d.ts.map \ No newline at end of file diff --git a/dist/verify.d.ts.map b/dist/verify.d.ts.map new file mode 100644 index 0000000..09f8a58 --- /dev/null +++ b/dist/verify.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAGtC;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,QAAQ,GAClB,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA6E/C"} \ No newline at end of file diff --git a/dist/verify.js b/dist/verify.js new file mode 100644 index 0000000..acee0ee --- /dev/null +++ b/dist/verify.js @@ -0,0 +1,115 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.validateExportStream = validateExportStream; +const tar = __importStar(require("tar-stream")); +const yaml_1 = __importDefault(require("yaml")); +/** + * Validates the structure and content of an exported ActivityPub tarball. + * @param tarStream - A ReadableStream containing the .tar archive. + * @returns A promise that resolves to an object with `valid` (boolean) and `errors` (string[]). + */ +async function validateExportStream(tarStream) { + console.log('Validating export stream...'); + const extract = tar.extract(); + const errors = []; + const requiredFiles = [ + 'manifest.yaml', // or 'manifest.yml' + 'activitypub/actor.json', + 'activitypub/outbox.json' + ].map((file) => file.toLowerCase()); // Normalize to lowercase for consistent comparison + const foundFiles = new Set(); + return await new Promise((resolve) => { + extract.on('entry', (header, stream, next) => { + const fileName = header.name.toLowerCase(); // Normalize file name + foundFiles.add(fileName); + let content = ''; + stream.on('data', (chunk) => { + content += chunk.toString(); + }); + stream.on('end', () => { + try { + // Validate JSON files + if (fileName.endsWith('.json')) { + JSON.parse(content); // Throws an error if content is not valid JSON + } + // Validate manifest file + if (fileName === 'manifest.yaml' || fileName === 'manifest.yml') { + const manifest = yaml_1.default.parse(content); + if (!manifest['ubc-version']) { + errors.push('Manifest is missing required field: ubc-version'); + } + if (!manifest.contents?.activitypub) { + errors.push('Manifest is missing required field: contents.activitypub'); + } + } + } + catch (error) { + errors.push(`Error processing file ${fileName}: ${error.message}`); + } + next(); + }); + stream.on('error', (error) => { + errors.push(`Stream error on file ${fileName}: ${error.message}`); + next(); + }); + }); + extract.on('finish', () => { + // Check if all required files are present + for (const file of requiredFiles) { + if (!foundFiles.has(file)) { + errors.push(`Missing required file: ${file}`); + } + } + resolve({ + valid: errors.length === 0, + errors + }); + }); + extract.on('error', (error) => { + errors.push(`Error during extraction: ${error.message}`); + resolve({ + valid: false, + errors + }); + }); + // Pipe the ReadableStream into the extractor + tarStream.pipe(extract); + }); +} +//# sourceMappingURL=verify.js.map \ No newline at end of file diff --git a/dist/verify.js.map b/dist/verify.js.map new file mode 100644 index 0000000..5a711c7 --- /dev/null +++ b/dist/verify.js.map @@ -0,0 +1 @@ +{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"} \ No newline at end of file