@luzzle/core 0.0.64 → 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.
@@ -43,6 +43,7 @@ declare class Pieces {
43
43
  };
44
44
  getSchemas(): Promise<string[]>;
45
45
  getTypes(): Promise<string[]>;
46
+ isAsset(filePath: string): boolean;
46
47
  getFilesIn(dir: string, options?: {
47
48
  deep?: boolean;
48
49
  }): Promise<{
@@ -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 if (!isHidden) {
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"]}