@luzzle/core 0.0.63 → 0.0.65
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/src/pieces/Pieces.d.ts +1 -0
- package/dist/src/pieces/Pieces.js +13 -3
- package/dist/src/pieces/Pieces.js.map +1 -1
- package/dist/src/pieces/utils/piece.d.ts +3 -0
- package/dist/src/pieces/utils/piece.js +33 -7
- package/dist/src/pieces/utils/piece.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -107,6 +107,10 @@ class Pieces {
|
|
|
107
107
|
const schemas = await this.getSchemas();
|
|
108
108
|
return schemas.map((schema) => path.basename(schema, '.json'));
|
|
109
109
|
}
|
|
110
|
+
isAsset(filePath) {
|
|
111
|
+
const normalized = path.normalize(filePath);
|
|
112
|
+
return normalized.startsWith(ASSETS_DIRECTORY + '/') || normalized === ASSETS_DIRECTORY;
|
|
113
|
+
}
|
|
110
114
|
async getFilesIn(dir, options) {
|
|
111
115
|
const types = await this.getTypes();
|
|
112
116
|
const readdir = await this._storage.getFilesIn(dir, options);
|
|
@@ -117,14 +121,20 @@ class Pieces {
|
|
|
117
121
|
types,
|
|
118
122
|
};
|
|
119
123
|
return readdir.reduce((files, file) => {
|
|
124
|
+
const fullPath = path.join(dir, file);
|
|
120
125
|
const extension = path.extname(file);
|
|
121
|
-
const isAsset = file.startsWith(ASSETS_DIRECTORY);
|
|
122
|
-
const isHidden = file.startsWith('.');
|
|
123
126
|
const isDirectory = file.endsWith('/');
|
|
127
|
+
const isHidden = file
|
|
128
|
+
.split(/[\\/]/)
|
|
129
|
+
.some((part) => part.startsWith('.') && part !== ASSETS_DIRECTORY && part !== '');
|
|
130
|
+
if (isHidden) {
|
|
131
|
+
return files;
|
|
132
|
+
}
|
|
133
|
+
const isAsset = this.isAsset(fullPath);
|
|
124
134
|
if (isAsset && !isDirectory) {
|
|
125
135
|
files.assets.push(file);
|
|
126
136
|
}
|
|
127
|
-
else
|
|
137
|
+
else {
|
|
128
138
|
if (isDirectory) {
|
|
129
139
|
files.directories.push(file);
|
|
130
140
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pieces.js","sourceRoot":"","sources":["../../../src/pieces/Pieces.ts"],"names":[],"mappings":"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","sourcesContent":["import Piece from './Piece.js'\nimport path from 'path'\nimport LuzzleStorage from '../storage/abstract.js'\nimport { jsonToPieceSchema } from './json.schema.js'\nimport { LuzzleDatabase } from '../database/tables/index.js'\nimport { addPiece, deletePiece, getPiece, getPieces, updatePiece } from './manager.js'\nimport {\n\tLUZZLE_DIRECTORY,\n\tLUZZLE_SCHEMAS_DIRECTORY,\n\tASSETS_DIRECTORY,\n\tLUZZLE_PIECE_FILE_EXTENSION,\n} from './assets.js'\nimport { Readable } from 'stream'\nimport { cpus } from 'os'\n\nexport type PiecesPruneResult =\n\t| {\n\t\taction: 'pruned'\n\t\tname: string\n\t\terror?: false\n\t}\n\t| {\n\t\tname: string\n\t\terror: true\n\t\tmessage: string\n\t}\n\nexport type PiecesSyncResult =\n\t| {\n\t\taction: 'added' | 'updated' | 'skipped'\n\t\tname: string\n\t\terror?: false\n\t}\n\t| {\n\t\tname: string\n\t\terror: true\n\t\tmessage: string\n\t}\n\nclass Pieces {\n\tprivate _storage: LuzzleStorage\n\n\tconstructor(storage: LuzzleStorage) {\n\t\tthis._storage = storage\n\t}\n\n\tasync getPiece(name: string) {\n\t\tconst schema = await this.getSchema(name)\n\t\treturn new Piece(name, this._storage, schema)\n\t}\n\n\tasync getPieceMarkdown(file: string, type?: string) {\n\t\tconst parts = this.parseFilename(file)\n\t\tconst pieceName = parts.type || type\n\n\t\tif (pieceName) {\n\t\t\tconst piece = await this.getPiece(pieceName)\n\t\t\treturn await piece.get(file)\n\t\t}\n\n\t\tthrow new Error(`invalid piece, can't determine piece type: ${file}`)\n\t}\n\n\tasync getPieceAsset(file: string) {\n\t\treturn (await this._storage.readFile(file)) as Buffer\n\t}\n\n\tgetSchemaPath(name: string) {\n\t\treturn path.join(LUZZLE_DIRECTORY, LUZZLE_SCHEMAS_DIRECTORY, `${name}.json`)\n\t}\n\n\tasync getSchema(name: string) {\n\t\tconst schemaPath = this.getSchemaPath(name)\n\t\tconst schemaJson = await this._storage.readFile(schemaPath, 'text')\n\t\treturn jsonToPieceSchema(schemaJson as string)\n\t}\n\n\tasync sync(db: LuzzleDatabase, options?: { dryRun?: boolean; force?: boolean }) {\n\t\tconst names = await this.getTypes()\n\t\tconst stream = Readable.from(names)\n\n\t\treturn stream.map(\n\t\t\tasync (name: string): Promise<PiecesSyncResult> => {\n\t\t\t\tconst piece = await getPiece(db, name)\n\t\t\t\tconst schemaPath = this.getSchemaPath(name)\n\t\t\t\tconst fileStat = await this._storage.stat(schemaPath).catch(() => null)\n\n\t\t\t\tif (fileStat) {\n\t\t\t\t\tconst schema = await this.getSchema(name)\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (!piece) {\n\t\t\t\t\t\t\tif (!options?.dryRun) {\n\t\t\t\t\t\t\t\tawait addPiece(db, name, schema)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn { action: 'added', name }\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst pieceDate = piece.date_updated || piece.date_added\n\t\t\t\t\t\t\tif (options?.force || fileStat.last_modified > new Date(pieceDate)) {\n\t\t\t\t\t\t\t\tif (!options?.dryRun) {\n\t\t\t\t\t\t\t\t\tawait updatePiece(db, name, schema)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn { action: 'updated', name }\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn { action: 'skipped', name }\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treturn { name, error: true, message: `error syncing piece: ${error}` }\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn { name, error: true, message: `schema file ${schemaPath} not found` }\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ concurrency: cpus().length }\n\t\t) as Readable & AsyncIterable<PiecesSyncResult>\n\t}\n\n\tasync prune(db: LuzzleDatabase, options?: { dryRun: boolean }) {\n\t\tconst names = await this.getTypes()\n\t\tconst dbPieces = await getPieces(db)\n\t\tconst diskPiecesSet = new Set<string>(names)\n\t\tconst missingPieces = dbPieces\n\t\t\t.filter((piece) => !diskPiecesSet.has(piece.name))\n\t\t\t.map((piece) => piece.name)\n\t\tconst stream = Readable.from(missingPieces)\n\n\t\treturn stream.map(\n\t\t\tasync (name: string): Promise<PiecesPruneResult> => {\n\t\t\t\ttry {\n\t\t\t\t\tif (!options?.dryRun) {\n\t\t\t\t\t\tawait deletePiece(db, name)\n\t\t\t\t\t}\n\t\t\t\t\treturn { action: 'pruned', name }\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn { name, error: true, message: `error pruning piece: ${error}` }\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ concurrency: cpus().length }\n\t\t) as Readable & AsyncIterable<PiecesPruneResult>\n\t}\n\n\tparseFilename(file: string) {\n\t\treturn {\n\t\t\tfile,\n\t\t\ttype: file.match(/\\.([^.]+)\\.[^.]+$/)?.[1] ?? null,\n\t\t\tformat: path.extname(file),\n\t\t\tslug: file.replace(/\\.[^.]+\\.[^.]+$/, ''),\n\t\t}\n\t}\n\n\tasync getSchemas() {\n\t\tconst schemaDir = path.join(LUZZLE_DIRECTORY, LUZZLE_SCHEMAS_DIRECTORY)\n\t\tconst readDir = await this._storage.getFilesIn(schemaDir)\n\n\t\treturn readDir.filter((file) => path.extname(file) === `.json`)\n\t}\n\n\tasync getTypes() {\n\t\tconst schemas = await this.getSchemas()\n\n\t\treturn schemas.map((schema) => path.basename(schema, '.json'))\n\t}\n\n\tasync getFilesIn(dir: string, options?: { deep?: boolean }) {\n\t\tconst types = await this.getTypes()\n\t\tconst readdir = await this._storage.getFilesIn(dir, options)\n\t\tconst result: {\n\t\t\ttypes: string[]\n\t\t\tpieces: string[]\n\t\t\tassets: string[]\n\t\t\tdirectories: string[]\n\t\t} = {\n\t\t\tpieces: [],\n\t\t\tassets: [],\n\t\t\tdirectories: [],\n\t\t\ttypes,\n\t\t}\n\n\t\treturn readdir.reduce((files, file) => {\n\t\t\tconst extension = path.extname(file)\n\t\t\tconst isAsset = file.startsWith(ASSETS_DIRECTORY)\n\t\t\tconst isHidden = file.startsWith('.')\n\t\t\tconst isDirectory = file.endsWith('/')\n\n\t\t\tif (isAsset && !isDirectory) {\n\t\t\t\tfiles.assets.push(file)\n\t\t\t} else if (!isHidden) {\n\t\t\t\tif (isDirectory) {\n\t\t\t\t\tfiles.directories.push(file)\n\t\t\t\t} else {\n\t\t\t\t\tconst type = this.parseFilename(file).type\n\t\t\t\t\tconst isMarkdown = extension === `.${LUZZLE_PIECE_FILE_EXTENSION}`\n\n\t\t\t\t\tif (type && types.includes(type) && isMarkdown) {\n\t\t\t\t\t\tfiles.pieces.push(file)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn files\n\t\t}, result)\n\t}\n}\n\nexport default Pieces\n"]}
|
|
1
|
+
{"version":3,"file":"Pieces.js","sourceRoot":"","sources":["../../../src/pieces/Pieces.ts"],"names":[],"mappings":"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","sourcesContent":["import Piece from './Piece.js'\nimport path from 'path'\nimport LuzzleStorage from '../storage/abstract.js'\nimport { jsonToPieceSchema } from './json.schema.js'\nimport { LuzzleDatabase } from '../database/tables/index.js'\nimport { addPiece, deletePiece, getPiece, getPieces, updatePiece } from './manager.js'\nimport {\n\tLUZZLE_DIRECTORY,\n\tLUZZLE_SCHEMAS_DIRECTORY,\n\tASSETS_DIRECTORY,\n\tLUZZLE_PIECE_FILE_EXTENSION,\n} from './assets.js'\nimport { Readable } from 'stream'\nimport { cpus } from 'os'\n\nexport type PiecesPruneResult =\n\t| {\n\t\taction: 'pruned'\n\t\tname: string\n\t\terror?: false\n\t}\n\t| {\n\t\tname: string\n\t\terror: true\n\t\tmessage: string\n\t}\n\nexport type PiecesSyncResult =\n\t| {\n\t\taction: 'added' | 'updated' | 'skipped'\n\t\tname: string\n\t\terror?: false\n\t}\n\t| {\n\t\tname: string\n\t\terror: true\n\t\tmessage: string\n\t}\n\nclass Pieces {\n\tprivate _storage: LuzzleStorage\n\n\tconstructor(storage: LuzzleStorage) {\n\t\tthis._storage = storage\n\t}\n\n\tasync getPiece(name: string) {\n\t\tconst schema = await this.getSchema(name)\n\t\treturn new Piece(name, this._storage, schema)\n\t}\n\n\tasync getPieceMarkdown(file: string, type?: string) {\n\t\tconst parts = this.parseFilename(file)\n\t\tconst pieceName = parts.type || type\n\n\t\tif (pieceName) {\n\t\t\tconst piece = await this.getPiece(pieceName)\n\t\t\treturn await piece.get(file)\n\t\t}\n\n\t\tthrow new Error(`invalid piece, can't determine piece type: ${file}`)\n\t}\n\n\tasync getPieceAsset(file: string) {\n\t\treturn (await this._storage.readFile(file)) as Buffer\n\t}\n\n\tgetSchemaPath(name: string) {\n\t\treturn path.join(LUZZLE_DIRECTORY, LUZZLE_SCHEMAS_DIRECTORY, `${name}.json`)\n\t}\n\n\tasync getSchema(name: string) {\n\t\tconst schemaPath = this.getSchemaPath(name)\n\t\tconst schemaJson = await this._storage.readFile(schemaPath, 'text')\n\t\treturn jsonToPieceSchema(schemaJson as string)\n\t}\n\n\tasync sync(db: LuzzleDatabase, options?: { dryRun?: boolean; force?: boolean }) {\n\t\tconst names = await this.getTypes()\n\t\tconst stream = Readable.from(names)\n\n\t\treturn stream.map(\n\t\t\tasync (name: string): Promise<PiecesSyncResult> => {\n\t\t\t\tconst piece = await getPiece(db, name)\n\t\t\t\tconst schemaPath = this.getSchemaPath(name)\n\t\t\t\tconst fileStat = await this._storage.stat(schemaPath).catch(() => null)\n\n\t\t\t\tif (fileStat) {\n\t\t\t\t\tconst schema = await this.getSchema(name)\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (!piece) {\n\t\t\t\t\t\t\tif (!options?.dryRun) {\n\t\t\t\t\t\t\t\tawait addPiece(db, name, schema)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn { action: 'added', name }\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst pieceDate = piece.date_updated || piece.date_added\n\t\t\t\t\t\t\tif (options?.force || fileStat.last_modified > new Date(pieceDate)) {\n\t\t\t\t\t\t\t\tif (!options?.dryRun) {\n\t\t\t\t\t\t\t\t\tawait updatePiece(db, name, schema)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn { action: 'updated', name }\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn { action: 'skipped', name }\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treturn { name, error: true, message: `error syncing piece: ${error}` }\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn { name, error: true, message: `schema file ${schemaPath} not found` }\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ concurrency: cpus().length }\n\t\t) as Readable & AsyncIterable<PiecesSyncResult>\n\t}\n\n\tasync prune(db: LuzzleDatabase, options?: { dryRun: boolean }) {\n\t\tconst names = await this.getTypes()\n\t\tconst dbPieces = await getPieces(db)\n\t\tconst diskPiecesSet = new Set<string>(names)\n\t\tconst missingPieces = dbPieces\n\t\t\t.filter((piece) => !diskPiecesSet.has(piece.name))\n\t\t\t.map((piece) => piece.name)\n\t\tconst stream = Readable.from(missingPieces)\n\n\t\treturn stream.map(\n\t\t\tasync (name: string): Promise<PiecesPruneResult> => {\n\t\t\t\ttry {\n\t\t\t\t\tif (!options?.dryRun) {\n\t\t\t\t\t\tawait deletePiece(db, name)\n\t\t\t\t\t}\n\t\t\t\t\treturn { action: 'pruned', name }\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn { name, error: true, message: `error pruning piece: ${error}` }\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ concurrency: cpus().length }\n\t\t) as Readable & AsyncIterable<PiecesPruneResult>\n\t}\n\n\tparseFilename(file: string) {\n\t\treturn {\n\t\t\tfile,\n\t\t\ttype: file.match(/\\.([^.]+)\\.[^.]+$/)?.[1] ?? null,\n\t\t\tformat: path.extname(file),\n\t\t\tslug: file.replace(/\\.[^.]+\\.[^.]+$/, ''),\n\t\t}\n\t}\n\n\tasync getSchemas() {\n\t\tconst schemaDir = path.join(LUZZLE_DIRECTORY, LUZZLE_SCHEMAS_DIRECTORY)\n\t\tconst readDir = await this._storage.getFilesIn(schemaDir)\n\n\t\treturn readDir.filter((file) => path.extname(file) === `.json`)\n\t}\n\n\tasync getTypes() {\n\t\tconst schemas = await this.getSchemas()\n\n\t\treturn schemas.map((schema) => path.basename(schema, '.json'))\n\t}\n\n\tisAsset(filePath: string): boolean {\n\t\tconst normalized = path.normalize(filePath)\n\t\treturn normalized.startsWith(ASSETS_DIRECTORY + '/') || normalized === ASSETS_DIRECTORY\n\t}\n\n\tasync getFilesIn(dir: string, options?: { deep?: boolean }) {\n\t\tconst types = await this.getTypes()\n\t\tconst readdir = await this._storage.getFilesIn(dir, options)\n\t\tconst result: {\n\t\t\ttypes: string[]\n\t\t\tpieces: string[]\n\t\t\tassets: string[]\n\t\t\tdirectories: string[]\n\t\t} = {\n\t\t\tpieces: [],\n\t\t\tassets: [],\n\t\t\tdirectories: [],\n\t\t\ttypes,\n\t\t}\n\n\t\treturn readdir.reduce((files, file) => {\n\t\t\tconst fullPath = path.join(dir, file)\n\t\t\tconst extension = path.extname(file)\n\t\t\tconst isDirectory = file.endsWith('/')\n\n\t\t\tconst isHidden = file\n\t\t\t\t.split(/[\\\\/]/)\n\t\t\t\t.some((part) => part.startsWith('.') && part !== ASSETS_DIRECTORY && part !== '')\n\n\t\t\tif (isHidden) {\n\t\t\t\treturn files\n\t\t\t}\n\n\t\t\tconst isAsset = this.isAsset(fullPath)\n\n\t\t\tif (isAsset && !isDirectory) {\n\t\t\t\tfiles.assets.push(file)\n\t\t\t} else {\n\t\t\t\tif (isDirectory) {\n\t\t\t\t\tfiles.directories.push(file)\n\t\t\t\t} else {\n\t\t\t\t\tconst type = this.parseFilename(file).type\n\t\t\t\t\tconst isMarkdown = extension === `.${LUZZLE_PIECE_FILE_EXTENSION}`\n\n\t\t\t\t\tif (type && types.includes(type) && isMarkdown) {\n\t\t\t\t\t\tfiles.pieces.push(file)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn files\n\t\t}, result)\n\t}\n}\n\nexport default Pieces\n"]}
|
|
@@ -11,6 +11,9 @@ declare function detectStreamFileType(stream: Readable, maxBytes?: number): Prom
|
|
|
11
11
|
stream: Readable;
|
|
12
12
|
}>;
|
|
13
13
|
declare function savePieceAsset(file: string, filename: string, stream: Readable, storage: LuzzleStorage): Promise<string>;
|
|
14
|
+
declare function savePieceAsset(file: string, source: string, storage: LuzzleStorage, options?: {
|
|
15
|
+
name?: string;
|
|
16
|
+
}): Promise<string>;
|
|
14
17
|
declare function savePieceFieldAsset(file: string, field: PieceFrontmatterSchemaField, stream: AttachableStream, storage: LuzzleStorage): Promise<string>;
|
|
15
18
|
declare function isAttachableStream(value: unknown): value is AttachableStream;
|
|
16
19
|
declare function makePieceValue(field: PieceFrontmatterSchemaField, value: PieceFrontMatterValue | AttachableStream): Promise<PieceFrontMatterValue | AttachableStream>;
|
|
@@ -100,21 +100,47 @@ async function detectStreamFileType(stream, maxBytes = 4100) {
|
|
|
100
100
|
stream: Readable.from(gen()),
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
|
-
async function savePieceAsset(file,
|
|
103
|
+
async function savePieceAsset(file, filenameOrSource, streamOrStorage, storageOrOptions) {
|
|
104
|
+
let finalStream;
|
|
105
|
+
let targetFilename;
|
|
106
|
+
let storage;
|
|
107
|
+
if (streamOrStorage &&
|
|
108
|
+
typeof streamOrStorage === 'object' &&
|
|
109
|
+
'pipe' in streamOrStorage &&
|
|
110
|
+
typeof streamOrStorage.pipe === 'function') {
|
|
111
|
+
targetFilename = filenameOrSource;
|
|
112
|
+
finalStream = streamOrStorage;
|
|
113
|
+
storage = storageOrOptions;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
storage = streamOrStorage;
|
|
117
|
+
const options = storageOrOptions;
|
|
118
|
+
const res = await downloadToStream(filenameOrSource);
|
|
119
|
+
finalStream = res.stream;
|
|
120
|
+
const originalFilename = res.filename || 'attachment';
|
|
121
|
+
if (options?.name) {
|
|
122
|
+
const ext = path.extname(originalFilename);
|
|
123
|
+
const hasExt = path.extname(options.name) !== '';
|
|
124
|
+
targetFilename = hasExt ? options.name : options.name + ext;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
targetFilename = originalFilename;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
104
130
|
const pieceDir = file.replace(/\.[^.]+$/, '');
|
|
105
131
|
const attachDir = path.join(ASSETS_DIRECTORY, pieceDir);
|
|
106
132
|
const exists = await storage.exists(attachDir);
|
|
107
133
|
if (!exists) {
|
|
108
134
|
await storage.makeDirectory(attachDir);
|
|
109
135
|
}
|
|
110
|
-
const { type: detectedType, stream:
|
|
111
|
-
const sourceBasename =
|
|
112
|
-
? path.basename(
|
|
136
|
+
const { type: detectedType, stream: detectedStream } = await detectStreamFileType(finalStream);
|
|
137
|
+
const sourceBasename = targetFilename
|
|
138
|
+
? path.basename(targetFilename, path.extname(targetFilename))
|
|
113
139
|
: 'attachment';
|
|
114
140
|
const sourceExt = detectedType
|
|
115
141
|
? '.' + detectedType.ext
|
|
116
|
-
:
|
|
117
|
-
? path.extname(
|
|
142
|
+
: targetFilename
|
|
143
|
+
? path.extname(targetFilename)
|
|
118
144
|
: '';
|
|
119
145
|
let relPath = path.join(attachDir, sourceBasename + sourceExt);
|
|
120
146
|
let counter = 2;
|
|
@@ -122,7 +148,7 @@ async function savePieceAsset(file, filename, stream, storage) {
|
|
|
122
148
|
relPath = path.join(attachDir, sourceBasename + '-' + counter + sourceExt);
|
|
123
149
|
counter++;
|
|
124
150
|
}
|
|
125
|
-
await pipeline(
|
|
151
|
+
await pipeline(detectedStream, storage.createWriteStream(relPath));
|
|
126
152
|
return relPath;
|
|
127
153
|
}
|
|
128
154
|
async function savePieceFieldAsset(file, field, stream, storage) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"piece.js","sourceRoot":"","sources":["../../../../src/pieces/utils/piece.ts"],"names":[],"mappings":"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","sourcesContent":["import { stat } from 'fs/promises'\nimport { createHash } from 'crypto'\nimport { Readable } from 'stream'\nimport { createReadStream } from 'fs'\nimport { pipeline } from 'stream/promises'\nimport path from 'path'\nimport { fileTypeFromBuffer } from 'file-type'\nimport got from 'got'\nimport { PieceFrontmatterSchemaField, PieceFrontMatterValue } from './frontmatter.js'\nimport LuzzleStorage from '../../storage/abstract.js'\nimport { ASSETS_DIRECTORY } from '../assets.js'\n\ntype AttachableStream = { stream: Readable; filename?: string }\n\nasync function downloadToStream(fileOrUrl: string): Promise<AttachableStream> {\n\tif (/https?:\\/\\//i.test(fileOrUrl)) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst download = got.stream(fileOrUrl, {\n\t\t\t\tthrowHttpErrors: false,\n\t\t\t\theaders: {\n\t\t\t\t\t'user-agent': 'luzzle/core (https://github.com/eleith/luzzle)',\n\t\t\t\t},\n\t\t\t\tretry: {\n\t\t\t\t\tlimit: 3,\n\t\t\t\t\tmethods: ['GET'],\n\t\t\t\t},\n\t\t\t\ttimeout: {\n\t\t\t\t\trequest: 10000,\n\t\t\t\t},\n\t\t\t})\n\t\t\tdownload.on('error', (err) => {\n\t\t\t\tconsole.error(`Error downloading file from ${fileOrUrl}: ${err.message}`)\n\t\t\t\treject(err)\n\t\t\t})\n\t\t\tdownload.on('response', (response) => {\n\t\t\t\tif (response.statusCode >= 400) {\n\t\t\t\t\tconsole.error(`Error downloading file from ${fileOrUrl}: http ${response.statusCode}`)\n\t\t\t\t\treject(new Error(`HTTP Error: ${response.statusCode}`))\n\t\t\t\t} else {\n\t\t\t\t\tconst filename = path.basename(new URL(fileOrUrl).pathname)\n\t\t\t\t\tresolve({ stream: download, filename })\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n\n\tconst file = fileOrUrl\n\tconst fileStat = await stat(file).catch(() => null)\n\n\tif (fileStat && fileStat.isFile()) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst stream = createReadStream(file)\n\t\t\tstream.on('error', (err) => {\n\t\t\t\tconsole.error(`Error reading file from path: ${err.message}`)\n\t\t\t\treject(err)\n\t\t\t})\n\t\t\tstream.on('open', () => {\n\t\t\t\tconst filename = path.basename(file)\n\t\t\t\tresolve({ stream, filename })\n\t\t\t})\n\t\t})\n\t}\n\n\tthrow new Error(`${fileOrUrl} is not a valid file`)\n}\n\nfunction calculateHashFromFile(stream: Readable): Promise<string> {\n\tconst hash = createHash('md5')\n\n\treturn new Promise((resolve, reject) => {\n\t\tstream.on('error', (err) => {\n\t\t\tconsole.error(`Error calculating hash from stream: ${err.message}`)\n\t\t\treject(err)\n\t\t})\n\t\tstream.on('data', (data) => hash.update(data))\n\t\tstream.on('end', () => resolve(hash.digest('hex')))\n\t})\n}\n\nasync function detectStreamFileType(stream: Readable, maxBytes = 4100) {\n\tconst iterator = stream[Symbol.asyncIterator]()\n\tconst chunks: Buffer[] = []\n\tlet length = 0\n\tlet done = false\n\n\twhile (length < maxBytes) {\n\t\tconst next = await iterator.next()\n\t\tif (next.done) {\n\t\t\tdone = true\n\t\t\tbreak\n\t\t}\n\t\tconst chunk = Buffer.isBuffer(next.value) ? next.value : Buffer.from(next.value)\n\t\tchunks.push(chunk)\n\t\tlength += chunk.length\n\t}\n\n\tconst buffer = Buffer.concat(chunks)\n\tconst type = await fileTypeFromBuffer(buffer)\n\n\tasync function* gen() {\n\t\tif (length > 0) yield buffer\n\t\tif (done) return\n\n\t\tlet next = await iterator.next()\n\t\twhile (!next.done) {\n\t\t\tyield next.value\n\t\t\tnext = await iterator.next()\n\t\t}\n\t}\n\n\treturn {\n\t\ttype,\n\t\tstream: Readable.from(gen()),\n\t}\n}\n\nasync function savePieceAsset(\n\tfile: string,\n\tfilename: string,\n\tstream: Readable,\n\tstorage: LuzzleStorage\n): Promise<string> {\n\tconst pieceDir = file.replace(/\\.[^.]+$/, '')\n\tconst attachDir = path.join(ASSETS_DIRECTORY, pieceDir)\n\tconst exists = await storage.exists(attachDir)\n\n\tif (!exists) {\n\t\tawait storage.makeDirectory(attachDir)\n\t}\n\n\tconst { type: detectedType, stream: finalStream } = await detectStreamFileType(stream)\n\n\tconst sourceBasename = filename\n\t\t? path.basename(filename, path.extname(filename))\n\t\t: 'attachment'\n\n\tconst sourceExt = detectedType\n\t\t? '.' + detectedType.ext\n\t\t: filename\n\t\t\t? path.extname(filename)\n\t\t\t: ''\n\n\tlet relPath = path.join(attachDir, sourceBasename + sourceExt)\n\tlet counter = 2\n\n\twhile (await storage.exists(relPath)) {\n\t\trelPath = path.join(attachDir, sourceBasename + '-' + counter + sourceExt)\n\t\tcounter++\n\t}\n\n\tawait pipeline(finalStream, storage.createWriteStream(relPath))\n\n\treturn relPath\n}\n\nasync function savePieceFieldAsset(\n\tfile: string,\n\tfield: PieceFrontmatterSchemaField,\n\tstream: AttachableStream,\n\tstorage: LuzzleStorage\n): Promise<string> {\n\tconst format = field.type === 'array' ? field.items.format : field.format\n\n\t/* c8 ignore next 3 */\n\tif (format !== 'asset') {\n\t\tthrow new Error(`${field} is not an attachable field for ${file}`)\n\t}\n\n\tconst filename = stream.filename || field.name\n\treturn savePieceAsset(file, filename, stream.stream, storage)\n}\n\nfunction isAttachableStream(value: unknown): value is AttachableStream {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t'stream' in value &&\n\t\ttypeof (value as AttachableStream).stream?.pipe === 'function'\n\t)\n}\n\nasync function makePieceValue(\n\tfield: PieceFrontmatterSchemaField,\n\tvalue: PieceFrontMatterValue | AttachableStream\n): Promise<PieceFrontMatterValue | AttachableStream> {\n\tconst isArray = field.type === 'array'\n\tconst format = isArray ? field.items.format : field.format\n\tconst type = isArray ? field.items.type : field.type\n\n\tif (format === 'asset') {\n\t\tif (typeof value === 'string') {\n\t\t\tif (value.startsWith(ASSETS_DIRECTORY)) {\n\t\t\t\treturn value\n\t\t\t}\n\t\t\treturn downloadToStream(value)\n\t\t} else if (typeof value === 'number' || typeof value === 'boolean' || Array.isArray(value)) {\n\t\t\tthrow new Error(`${field} must be a string or stream`)\n\t\t} else {\n\t\t\treturn value\n\t\t}\n\t} else if (type === 'boolean') {\n\t\treturn /1|true|yes/.test(value as string)\n\t} else if (type === 'integer') {\n\t\treturn parseInt(value as string)\n\t}\n\n\treturn value\n}\n\nexport {\n\tcalculateHashFromFile,\n\tisAttachableStream,\n\tsavePieceFieldAsset,\n\tmakePieceValue,\n\tdetectStreamFileType,\n\tsavePieceAsset,\n\ttype AttachableStream,\n}\n"]}
|
|
1
|
+
{"version":3,"file":"piece.js","sourceRoot":"","sources":["../../../../src/pieces/utils/piece.ts"],"names":[],"mappings":"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","sourcesContent":["import { stat } from 'fs/promises'\nimport { createHash } from 'crypto'\nimport { Readable } from 'stream'\nimport { createReadStream } from 'fs'\nimport { pipeline } from 'stream/promises'\nimport path from 'path'\nimport { fileTypeFromBuffer } from 'file-type'\nimport got from 'got'\nimport { PieceFrontmatterSchemaField, PieceFrontMatterValue } from './frontmatter.js'\nimport LuzzleStorage from '../../storage/abstract.js'\nimport { ASSETS_DIRECTORY } from '../assets.js'\n\ntype AttachableStream = { stream: Readable; filename?: string }\n\nasync function downloadToStream(fileOrUrl: string): Promise<AttachableStream> {\n\tif (/https?:\\/\\//i.test(fileOrUrl)) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst download = got.stream(fileOrUrl, {\n\t\t\t\tthrowHttpErrors: false,\n\t\t\t\theaders: {\n\t\t\t\t\t'user-agent': 'luzzle/core (https://github.com/eleith/luzzle)',\n\t\t\t\t},\n\t\t\t\tretry: {\n\t\t\t\t\tlimit: 3,\n\t\t\t\t\tmethods: ['GET'],\n\t\t\t\t},\n\t\t\t\ttimeout: {\n\t\t\t\t\trequest: 10000,\n\t\t\t\t},\n\t\t\t})\n\t\t\tdownload.on('error', (err) => {\n\t\t\t\tconsole.error(`Error downloading file from ${fileOrUrl}: ${err.message}`)\n\t\t\t\treject(err)\n\t\t\t})\n\t\t\tdownload.on('response', (response) => {\n\t\t\t\tif (response.statusCode >= 400) {\n\t\t\t\t\tconsole.error(`Error downloading file from ${fileOrUrl}: http ${response.statusCode}`)\n\t\t\t\t\treject(new Error(`HTTP Error: ${response.statusCode}`))\n\t\t\t\t} else {\n\t\t\t\t\tconst filename = path.basename(new URL(fileOrUrl).pathname)\n\t\t\t\t\tresolve({ stream: download, filename })\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n\n\tconst file = fileOrUrl\n\tconst fileStat = await stat(file).catch(() => null)\n\n\tif (fileStat && fileStat.isFile()) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst stream = createReadStream(file)\n\t\t\tstream.on('error', (err) => {\n\t\t\t\tconsole.error(`Error reading file from path: ${err.message}`)\n\t\t\t\treject(err)\n\t\t\t})\n\t\t\tstream.on('open', () => {\n\t\t\t\tconst filename = path.basename(file)\n\t\t\t\tresolve({ stream, filename })\n\t\t\t})\n\t\t})\n\t}\n\n\tthrow new Error(`${fileOrUrl} is not a valid file`)\n}\n\nfunction calculateHashFromFile(stream: Readable): Promise<string> {\n\tconst hash = createHash('md5')\n\n\treturn new Promise((resolve, reject) => {\n\t\tstream.on('error', (err) => {\n\t\t\tconsole.error(`Error calculating hash from stream: ${err.message}`)\n\t\t\treject(err)\n\t\t})\n\t\tstream.on('data', (data) => hash.update(data))\n\t\tstream.on('end', () => resolve(hash.digest('hex')))\n\t})\n}\n\nasync function detectStreamFileType(stream: Readable, maxBytes = 4100) {\n\tconst iterator = stream[Symbol.asyncIterator]()\n\tconst chunks: Buffer[] = []\n\tlet length = 0\n\tlet done = false\n\n\twhile (length < maxBytes) {\n\t\tconst next = await iterator.next()\n\t\tif (next.done) {\n\t\t\tdone = true\n\t\t\tbreak\n\t\t}\n\t\tconst chunk = Buffer.isBuffer(next.value) ? next.value : Buffer.from(next.value)\n\t\tchunks.push(chunk)\n\t\tlength += chunk.length\n\t}\n\n\tconst buffer = Buffer.concat(chunks)\n\tconst type = await fileTypeFromBuffer(buffer)\n\n\tasync function* gen() {\n\t\tif (length > 0) yield buffer\n\t\tif (done) return\n\n\t\tlet next = await iterator.next()\n\t\twhile (!next.done) {\n\t\t\tyield next.value\n\t\t\tnext = await iterator.next()\n\t\t}\n\t}\n\n\treturn {\n\t\ttype,\n\t\tstream: Readable.from(gen()),\n\t}\n}\n\nasync function savePieceAsset(\n\tfile: string,\n\tfilename: string,\n\tstream: Readable,\n\tstorage: LuzzleStorage\n): Promise<string>\nasync function savePieceAsset(\n\tfile: string,\n\tsource: string,\n\tstorage: LuzzleStorage,\n\toptions?: { name?: string }\n): Promise<string>\nasync function savePieceAsset(\n\tfile: string,\n\tfilenameOrSource: string,\n\tstreamOrStorage: Readable | LuzzleStorage,\n\tstorageOrOptions?: LuzzleStorage | { name?: string }\n): Promise<string> {\n\tlet finalStream: Readable\n\tlet targetFilename: string\n\tlet storage: LuzzleStorage\n\n\tif (\n\t\tstreamOrStorage &&\n\t\ttypeof streamOrStorage === 'object' &&\n\t\t'pipe' in streamOrStorage &&\n\t\ttypeof (streamOrStorage as unknown as Readable).pipe === 'function'\n\t) {\n\t\ttargetFilename = filenameOrSource\n\t\tfinalStream = streamOrStorage as Readable\n\t\tstorage = storageOrOptions as LuzzleStorage\n\t} else {\n\t\tstorage = streamOrStorage as LuzzleStorage\n\t\tconst options = storageOrOptions as { name?: string } | undefined\n\t\tconst res = await downloadToStream(filenameOrSource)\n\t\tfinalStream = res.stream\n\t\tconst originalFilename = res.filename || 'attachment'\n\t\tif (options?.name) {\n\t\t\tconst ext = path.extname(originalFilename)\n\t\t\tconst hasExt = path.extname(options.name) !== ''\n\t\t\ttargetFilename = hasExt ? options.name : options.name + ext\n\t\t} else {\n\t\t\ttargetFilename = originalFilename\n\t\t}\n\t}\n\n\tconst pieceDir = file.replace(/\\.[^.]+$/, '')\n\tconst attachDir = path.join(ASSETS_DIRECTORY, pieceDir)\n\tconst exists = await storage.exists(attachDir)\n\n\tif (!exists) {\n\t\tawait storage.makeDirectory(attachDir)\n\t}\n\n\tconst { type: detectedType, stream: detectedStream } = await detectStreamFileType(finalStream)\n\n\tconst sourceBasename = targetFilename\n\t\t? path.basename(targetFilename, path.extname(targetFilename))\n\t\t: 'attachment'\n\n\tconst sourceExt = detectedType\n\t\t? '.' + detectedType.ext\n\t\t: targetFilename\n\t\t\t? path.extname(targetFilename)\n\t\t\t: ''\n\n\tlet relPath = path.join(attachDir, sourceBasename + sourceExt)\n\tlet counter = 2\n\n\twhile (await storage.exists(relPath)) {\n\t\trelPath = path.join(attachDir, sourceBasename + '-' + counter + sourceExt)\n\t\tcounter++\n\t}\n\n\tawait pipeline(detectedStream, storage.createWriteStream(relPath))\n\n\treturn relPath\n}\n\nasync function savePieceFieldAsset(\n\tfile: string,\n\tfield: PieceFrontmatterSchemaField,\n\tstream: AttachableStream,\n\tstorage: LuzzleStorage\n): Promise<string> {\n\tconst format = field.type === 'array' ? field.items.format : field.format\n\n\t/* c8 ignore next 3 */\n\tif (format !== 'asset') {\n\t\tthrow new Error(`${field} is not an attachable field for ${file}`)\n\t}\n\n\tconst filename = stream.filename || field.name\n\treturn savePieceAsset(file, filename, stream.stream, storage)\n}\n\nfunction isAttachableStream(value: unknown): value is AttachableStream {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t'stream' in value &&\n\t\ttypeof (value as AttachableStream).stream?.pipe === 'function'\n\t)\n}\n\nasync function makePieceValue(\n\tfield: PieceFrontmatterSchemaField,\n\tvalue: PieceFrontMatterValue | AttachableStream\n): Promise<PieceFrontMatterValue | AttachableStream> {\n\tconst isArray = field.type === 'array'\n\tconst format = isArray ? field.items.format : field.format\n\tconst type = isArray ? field.items.type : field.type\n\n\tif (format === 'asset') {\n\t\tif (typeof value === 'string') {\n\t\t\tif (value.startsWith(ASSETS_DIRECTORY)) {\n\t\t\t\treturn value\n\t\t\t}\n\t\t\treturn downloadToStream(value)\n\t\t} else if (typeof value === 'number' || typeof value === 'boolean' || Array.isArray(value)) {\n\t\t\tthrow new Error(`${field} must be a string or stream`)\n\t\t} else {\n\t\t\treturn value\n\t\t}\n\t} else if (type === 'boolean') {\n\t\treturn /1|true|yes/.test(value as string)\n\t} else if (type === 'integer') {\n\t\treturn parseInt(value as string)\n\t}\n\n\treturn value\n}\n\nexport {\n\tcalculateHashFromFile,\n\tisAttachableStream,\n\tsavePieceFieldAsset,\n\tmakePieceValue,\n\tdetectStreamFileType,\n\tsavePieceAsset,\n\ttype AttachableStream,\n}\n"]}
|