UNPKG

@shockpkg/dir-projector

Version:

Package for creating Shockwave Director projectors

1 lines 26.2 kB
{"version":3,"file":"bundle.mjs","names":["createReadStream","createWriteStream","chmod","lstat","mkdir","readdir","readlink","stat","symlink","utimes","Readable","pipeline","join","pathJoin","dirname","basename","resolve","fsLchmod","fsLutimes","fsWalk","fsLstatExists","Queue","userExec","Bundle","excludes","_isOpen","_closeQueue","constructor","path","flat","isOpen","isExcludedFile","name","exclude","test","open","Error","_checkOutput","clear","_open","close","_assertIsOpen","_close","write","func","call","resourcePath","destination","projector","resourceExists","copyResource","source","options","isSymbolicLink","copyResourceSymlink","isFile","copyResourceFile","isDirectory","copyResourceDirectory","createResourceDirectory","_expandResourceOptionsCopy","noRecurse","opts","streamResourceFile","createResourceSymlink","dest","_assertNotResourceExists","merge","recursive","atime","mtime","abs","push","_setResourceAttributes","bind","length","createResourceFile","data","read","target","t","Buffer","from","buffer","byteOffset","byteLength","p","n","Promise","all","map","r","st","atimeCopy","mtimeCopy","executable","executableCopy","_getResourceModeExecutable","mode","_setResourceModeExecutable","run","ignoreDirectory","_getProjectorPath","_getProjectorPathNested"],"sources":["../src/bundle.ts"],"sourcesContent":["import {createReadStream, createWriteStream} from 'node:fs';\nimport {\n\tchmod,\n\tlstat,\n\tmkdir,\n\treaddir,\n\treadlink,\n\tstat,\n\tsymlink,\n\tutimes\n} from 'node:fs/promises';\nimport {Readable} from 'node:stream';\nimport {pipeline} from 'node:stream/promises';\nimport {join as pathJoin, dirname, basename, resolve} from 'node:path';\n\nimport {\n\tfsLchmod,\n\tfsLutimes,\n\tfsWalk,\n\tfsLstatExists\n} from '@shockpkg/archive-files';\n\nimport {Queue} from './queue.ts';\nimport {Projector} from './projector.ts';\n\nconst userExec = 0b001000000;\n\n/**\n * Options for adding resources.\n */\nexport interface IBundleResourceOptions {\n\t/**\n\t * Access time.\n\t */\n\tatime?: null | Date;\n\n\t/**\n\t * Copy source atime if not set.\n\t */\n\tatimeCopy?: null | boolean;\n\n\t/**\n\t * Modification time.\n\t */\n\tmtime?: null | Date;\n\n\t/**\n\t * Copy source mtime if not set.\n\t */\n\tmtimeCopy?: null | boolean;\n\n\t/**\n\t * Mark files and symlinks as executable.\n\t */\n\texecutable?: null | boolean;\n\n\t/**\n\t * Copy source executable if not set.\n\t */\n\texecutableCopy?: null | boolean;\n\n\t/**\n\t * Optionally merge directory contents.\n\t */\n\tmerge?: null | boolean;\n\n\t/**\n\t * Skip recursive directory copy.\n\t */\n\tnoRecurse?: null | boolean;\n}\n\n/**\n * Bundle object.\n */\nexport abstract class Bundle {\n\t/**\n\t * File and directory names to exclude when adding a directory.\n\t */\n\t// eslint-disable-next-line unicorn/better-regex\n\tpublic excludes = [/^\\./, /^ehthumbs\\.db$/i, /^Thumbs\\.db$/i];\n\n\t/**\n\t * Bundle main executable path.\n\t */\n\tpublic readonly path: string;\n\n\t/**\n\t * Flat bundle.\n\t */\n\tpublic readonly flat: boolean;\n\n\t/**\n\t * Projector instance.\n\t */\n\tpublic abstract readonly projector: Projector;\n\n\t/**\n\t * Open flag.\n\t */\n\tprotected _isOpen = false;\n\n\t/**\n\t * Close callbacks priority queue.\n\t */\n\tprotected _closeQueue = new Queue();\n\n\t/**\n\t * Bundle constructor.\n\t *\n\t * @param path Output path for the main executable.\n\t * @param flat Flat bundle.\n\t */\n\tconstructor(path: string, flat = false) {\n\t\tthis.path = path;\n\t\tthis.flat = flat;\n\t}\n\n\t/**\n\t * Check if output open.\n\t *\n\t * @returns Returns true if open, else false.\n\t */\n\tpublic get isOpen() {\n\t\treturn this._isOpen;\n\t}\n\n\t/**\n\t * Check if name is excluded file.\n\t *\n\t * @param name File name.\n\t * @returns Returns true if excluded, else false.\n\t */\n\tpublic isExcludedFile(name: string) {\n\t\tfor (const exclude of this.excludes) {\n\t\t\tif (exclude.test(name)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Open output.\n\t */\n\tpublic async open() {\n\t\tif (this._isOpen) {\n\t\t\tthrow new Error('Already open');\n\t\t}\n\t\tawait this._checkOutput();\n\n\t\tthis._closeQueue.clear();\n\t\tawait this._open();\n\n\t\tthis._isOpen = true;\n\t}\n\n\t/**\n\t * Close output.\n\t */\n\tpublic async close() {\n\t\tthis._assertIsOpen();\n\n\t\ttry {\n\t\t\tawait this._close();\n\t\t} finally {\n\t\t\tthis._closeQueue.clear();\n\t\t}\n\n\t\tthis._isOpen = false;\n\t}\n\n\t/**\n\t * Write out the bundle.\n\t * Has a callback to write out the resources.\n\t *\n\t * @param func Async function.\n\t * @returns Return value of the async function.\n\t */\n\tpublic async write<T>(func: ((self: this) => Promise<T>) | null = null) {\n\t\tawait this.open();\n\t\ttry {\n\t\t\treturn func ? await func.call(this, this) : null;\n\t\t} finally {\n\t\t\tawait this.close();\n\t\t}\n\t}\n\n\t/**\n\t * Get path for resource.\n\t *\n\t * @param destination Resource destination.\n\t * @returns Destination path.\n\t */\n\tpublic resourcePath(destination: string) {\n\t\treturn pathJoin(dirname(this.projector.path), destination);\n\t}\n\n\t/**\n\t * Check if path for resource exists.\n\t *\n\t * @param destination Resource destination.\n\t * @returns True if destination exists, else false.\n\t */\n\tpublic async resourceExists(destination: string) {\n\t\treturn !!(await fsLstatExists(this.resourcePath(destination)));\n\t}\n\n\t/**\n\t * Copy resource, detecting source type automatically.\n\t *\n\t * @param destination Resource destination.\n\t * @param source Source directory.\n\t * @param options Resource options.\n\t */\n\tpublic async copyResource(\n\t\tdestination: string,\n\t\tsource: string,\n\t\toptions: Readonly<IBundleResourceOptions> | null = null\n\t) {\n\t\tthis._assertIsOpen();\n\n\t\tconst stat = await lstat(source);\n\t\tswitch (true) {\n\t\t\tcase stat.isSymbolicLink(): {\n\t\t\t\tawait this.copyResourceSymlink(destination, source, options);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase stat.isFile(): {\n\t\t\t\tawait this.copyResourceFile(destination, source, options);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase stat.isDirectory(): {\n\t\t\t\tawait this.copyResourceDirectory(destination, source, options);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow new Error(`Unsupported resource type: ${source}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Copy directory as resource, recursive copy.\n\t *\n\t * @param destination Resource destination.\n\t * @param source Source directory.\n\t * @param options Resource options.\n\t */\n\tpublic async copyResourceDirectory(\n\t\tdestination: string,\n\t\tsource: string,\n\t\toptions: Readonly<IBundleResourceOptions> | null = null\n\t) {\n\t\tthis._assertIsOpen();\n\n\t\t// Create directory.\n\t\tawait this.createResourceDirectory(\n\t\t\tdestination,\n\t\t\toptions\n\t\t\t\t? await this._expandResourceOptionsCopy(options, async () =>\n\t\t\t\t\t\tstat(source)\n\t\t\t\t\t)\n\t\t\t\t: options\n\t\t);\n\n\t\t// If not recursive do not walk contents.\n\t\tif (options && options.noRecurse) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Any directories we add should not be recursive.\n\t\tconst opts = {\n\t\t\t...options,\n\t\t\tnoRecurse: true\n\t\t};\n\t\tawait fsWalk(source, async (path, stat) => {\n\t\t\t// If this name is excluded, skip without descending.\n\t\t\tif (this.isExcludedFile(basename(path))) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tawait this.copyResource(\n\t\t\t\tpathJoin(destination, path),\n\t\t\t\tpathJoin(source, path),\n\t\t\t\topts\n\t\t\t);\n\t\t\treturn true;\n\t\t});\n\t}\n\n\t/**\n\t * Copy file as resource.\n\t *\n\t * @param destination Resource destination.\n\t * @param source Source file.\n\t * @param options Resource options.\n\t */\n\tpublic async copyResourceFile(\n\t\tdestination: string,\n\t\tsource: string,\n\t\toptions: Readonly<IBundleResourceOptions> | null = null\n\t) {\n\t\tthis._assertIsOpen();\n\n\t\tawait this.streamResourceFile(\n\t\t\tdestination,\n\t\t\tcreateReadStream(source),\n\t\t\toptions\n\t\t\t\t? await this._expandResourceOptionsCopy(options, async () =>\n\t\t\t\t\t\tstat(source)\n\t\t\t\t\t)\n\t\t\t\t: options\n\t\t);\n\t}\n\n\t/**\n\t * Copy symlink as resource.\n\t *\n\t * @param destination Resource destination.\n\t * @param source Source symlink.\n\t * @param options Resource options.\n\t */\n\tpublic async copyResourceSymlink(\n\t\tdestination: string,\n\t\tsource: string,\n\t\toptions: Readonly<IBundleResourceOptions> | null = null\n\t) {\n\t\tthis._assertIsOpen();\n\n\t\tawait this.createResourceSymlink(\n\t\t\tdestination,\n\t\t\tawait readlink(source),\n\t\t\toptions\n\t\t\t\t? await this._expandResourceOptionsCopy(options, async () =>\n\t\t\t\t\t\tlstat(source)\n\t\t\t\t\t)\n\t\t\t\t: options\n\t\t);\n\t}\n\n\t/**\n\t * Create a resource directory.\n\t *\n\t * @param destination Resource destination.\n\t * @param options Resource options.\n\t */\n\tpublic async createResourceDirectory(\n\t\tdestination: string,\n\t\toptions: Readonly<IBundleResourceOptions> | null = null\n\t) {\n\t\tthis._assertIsOpen();\n\n\t\tconst dest = await this._assertNotResourceExists(\n\t\t\tdestination,\n\t\t\t!!(options && options.merge)\n\t\t);\n\t\tawait mkdir(dest, {recursive: true});\n\n\t\t// If either is set, queue up change times when closing.\n\t\tif (options && (options.atime || options.mtime)) {\n\t\t\t// Get absolute path, use length for the priority.\n\t\t\t// Also copy the options object which the owner could change.\n\t\t\tconst abs = resolve(dest);\n\t\t\tthis._closeQueue.push(\n\t\t\t\tthis._setResourceAttributes.bind(this, abs, {...options}),\n\t\t\t\tabs.length\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Create a resource file.\n\t *\n\t * @param destination Resource destination.\n\t * @param data Resource data.\n\t * @param options Resource options.\n\t */\n\tpublic async createResourceFile(\n\t\tdestination: string,\n\t\tdata: Readonly<Uint8Array> | string,\n\t\toptions: Readonly<IBundleResourceOptions> | null = null\n\t) {\n\t\tthis._assertIsOpen();\n\n\t\tawait this.streamResourceFile(\n\t\t\tdestination,\n\t\t\tnew Readable({\n\t\t\t\t/**\n\t\t\t\t * Read method.\n\t\t\t\t */\n\t\t\t\tread() {\n\t\t\t\t\tthis.push(data);\n\t\t\t\t\tthis.push(null);\n\t\t\t\t}\n\t\t\t}),\n\t\t\toptions\n\t\t);\n\t}\n\n\t/**\n\t * Create a resource symlink.\n\t *\n\t * @param destination Resource destination.\n\t * @param target Symlink target.\n\t * @param options Resource options.\n\t */\n\tpublic async createResourceSymlink(\n\t\tdestination: string,\n\t\ttarget: Readonly<Uint8Array> | string,\n\t\toptions: Readonly<IBundleResourceOptions> | null = null\n\t) {\n\t\tthis._assertIsOpen();\n\n\t\tconst dest = await this._assertNotResourceExists(destination);\n\t\tawait mkdir(dirname(dest), {recursive: true});\n\t\tconst t =\n\t\t\ttypeof target === 'string'\n\t\t\t\t? target\n\t\t\t\t: Buffer.from(\n\t\t\t\t\t\ttarget.buffer,\n\t\t\t\t\t\ttarget.byteOffset,\n\t\t\t\t\t\ttarget.byteLength\n\t\t\t\t\t);\n\t\tawait symlink(t, dest);\n\n\t\tif (options) {\n\t\t\tawait this._setResourceAttributes(dest, options);\n\t\t}\n\t}\n\n\t/**\n\t * Stream readable source to resource file.\n\t *\n\t * @param destination Resource destination.\n\t * @param data Resource stream.\n\t * @param options Resource options.\n\t */\n\tpublic async streamResourceFile(\n\t\tdestination: string,\n\t\tdata: Readable,\n\t\toptions: Readonly<IBundleResourceOptions> | null = null\n\t) {\n\t\tthis._assertIsOpen();\n\n\t\tconst dest = await this._assertNotResourceExists(destination);\n\t\tawait mkdir(dirname(dest), {recursive: true});\n\t\tawait pipeline(data, createWriteStream(dest));\n\n\t\tif (options) {\n\t\t\tawait this._setResourceAttributes(dest, options);\n\t\t}\n\t}\n\n\t/**\n\t * Check that output path is valid, else throws.\n\t */\n\tprotected async _checkOutput() {\n\t\tif (this.flat) {\n\t\t\tconst p = dirname(this.path);\n\t\t\tif (await fsLstatExists(p)) {\n\t\t\t\tfor (const n of await readdir(p)) {\n\t\t\t\t\tif (!this.isExcludedFile(n)) {\n\t\t\t\t\t\tthrow new Error(`Output path not empty: ${p}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tawait Promise.all(\n\t\t\t[this.path, this.resourcePath('')].map(async p => {\n\t\t\t\tif (await fsLstatExists(p)) {\n\t\t\t\t\tthrow new Error(`Output path already exists: ${p}`);\n\t\t\t\t}\n\t\t\t})\n\t\t);\n\t}\n\n\t/**\n\t * Expand resource options copy properties with stat object from source.\n\t *\n\t * @param options Options object.\n\t * @param stat Stat function.\n\t * @returns Options copy with any values populated.\n\t */\n\tprotected async _expandResourceOptionsCopy(\n\t\toptions: Readonly<IBundleResourceOptions>,\n\t\tstat: () => Promise<{\n\t\t\tatime: Date;\n\t\t\tmtime: Date;\n\t\t\tmode: number;\n\t\t}>\n\t) {\n\t\tconst r = {...options} as IBundleResourceOptions;\n\t\tlet st;\n\t\tif (!r.atime && r.atimeCopy) {\n\t\t\tst = await stat();\n\t\t\tr.atime = st.atime;\n\t\t}\n\t\tif (!r.mtime && r.mtimeCopy) {\n\t\t\tst ??= await stat();\n\t\t\tr.mtime = st.mtime;\n\t\t}\n\t\tif (typeof r.executable !== 'boolean' && r.executableCopy) {\n\t\t\tst ??= await stat();\n\t\t\tr.executable = this._getResourceModeExecutable(st.mode);\n\t\t}\n\t\treturn r;\n\t}\n\n\t/**\n\t * Set resource attributes from options object.\n\t *\n\t * @param path File path.\n\t * @param options Options object.\n\t */\n\tprotected async _setResourceAttributes(\n\t\tpath: string,\n\t\toptions: Readonly<IBundleResourceOptions>\n\t) {\n\t\tconst {atime, mtime, executable} = options;\n\t\tconst st = await lstat(path);\n\n\t\t// Maybe set executable if not a directory.\n\t\tif (typeof executable === 'boolean' && !st.isDirectory()) {\n\t\t\t// eslint-disable-next-line unicorn/prefer-ternary\n\t\t\tif (st.isSymbolicLink()) {\n\t\t\t\tawait fsLchmod(\n\t\t\t\t\tpath,\n\t\t\t\t\tthis._setResourceModeExecutable(\n\t\t\t\t\t\t// Workaround for a legacy Node issue.\n\t\t\t\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\t\t\t\tst.mode & 0b111111111,\n\t\t\t\t\t\texecutable\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tawait chmod(\n\t\t\t\t\tpath,\n\t\t\t\t\tthis._setResourceModeExecutable(st.mode, executable)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Maybe change times if either is set.\n\t\tif (atime || mtime) {\n\t\t\t// eslint-disable-next-line unicorn/prefer-ternary\n\t\t\tif (st.isSymbolicLink()) {\n\t\t\t\tawait fsLutimes(path, atime || st.atime, mtime || st.mtime);\n\t\t\t} else {\n\t\t\t\tawait utimes(path, atime || st.atime, mtime || st.mtime);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get file mode executable.\n\t *\n\t * @param mode Current mode.\n\t * @returns Is executable.\n\t */\n\tprotected _getResourceModeExecutable(mode: number) {\n\t\t// eslint-disable-next-line no-bitwise\n\t\treturn !!(mode & userExec);\n\t}\n\n\t/**\n\t * Set file mode executable.\n\t *\n\t * @param mode Current mode.\n\t * @param executable Is executable.\n\t * @returns File mode.\n\t */\n\tprotected _setResourceModeExecutable(mode: number, executable: boolean) {\n\t\t// eslint-disable-next-line no-bitwise\n\t\treturn (executable ? mode | userExec : mode & ~userExec) >>> 0;\n\t}\n\n\t/**\n\t * Open output.\n\t */\n\tprotected async _open() {\n\t\tawait this.projector.write();\n\t}\n\n\t/**\n\t * Close output.\n\t */\n\tprotected async _close() {\n\t\tawait this._closeQueue.run();\n\t}\n\n\t/**\n\t * Assert bundle is open.\n\t */\n\tprotected _assertIsOpen() {\n\t\tif (!this._isOpen) {\n\t\t\tthrow new Error('Not open');\n\t\t}\n\t}\n\n\t/**\n\t * Assert resource does not exist, returning destination path.\n\t *\n\t * @param destination Resource destination.\n\t * @param ignoreDirectory Ignore directories.\n\t * @returns Destination path.\n\t */\n\tprotected async _assertNotResourceExists(\n\t\tdestination: string,\n\t\tignoreDirectory = false\n\t) {\n\t\tconst dest = this.resourcePath(destination);\n\t\tconst st = await fsLstatExists(dest);\n\t\tif (st && (!ignoreDirectory || !st.isDirectory())) {\n\t\t\tthrow new Error(`Resource path exists: ${dest}`);\n\t\t}\n\t\treturn dest;\n\t}\n\n\t/**\n\t * Get the projector path.\n\t *\n\t * @returns This path or the nested path.\n\t */\n\tprotected _getProjectorPath() {\n\t\treturn this.flat ? this.path : this._getProjectorPathNested();\n\t}\n\n\t/**\n\t * Get nested projector path.\n\t *\n\t * @returns Output path.\n\t */\n\tprotected abstract _getProjectorPathNested(): string;\n\n\t/**\n\t * Create projector instance for the bundle.\n\t *\n\t * @returns Projector instance.\n\t */\n\tprotected abstract _createProjector(): Projector;\n}\n"],"mappings":"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","ignoreList":[]}