@sketch-hq/sketch-file
Version:
Utilities to read and write Sketch documents
95 lines (94 loc) • 4.54 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.toFile = exports.fromFile = void 0;
const path_1 = __importDefault(require("path"));
const node_stream_zip_1 = __importDefault(require("node-stream-zip"));
const adm_zip_1 = __importDefault(require("adm-zip"));
/**
* Reads and parses Sketch documents.
*
* @param filepath - The file path to the Sketch document
* @returns A {@link Promise} that resolves with a fully parsed {@link SketchFile} object once the file at the given path has been unzipped and read successfully
*/
const fromFile = (filepath) => __awaiter(void 0, void 0, void 0, function* () {
const archive = new node_stream_zip_1.default({
file: filepath,
storeEntries: true,
});
const contents = yield new Promise((resolve) => {
archive.on('ready', () => {
const document = JSON.parse(archive.entryDataSync('document.json').toString());
const pages = document.pages.map((page) => JSON.parse(archive.entryDataSync(`${page._ref}.json`).toString()));
const workspace = Object.keys(archive.entries())
.filter((key) => key.startsWith('workspace/'))
.filter((key) => key.endsWith('.json'))
.reduce((acc, key) => {
return Object.assign(Object.assign({}, acc), { [path_1.default.basename(key, '.json')]: JSON.parse(archive.entryDataSync(key).toString()) });
}, {});
resolve({
document: Object.assign(Object.assign({}, document), { pages }),
meta: JSON.parse(archive.entryDataSync('meta.json').toString()),
user: JSON.parse(archive.entryDataSync('user.json').toString()),
workspace,
});
});
});
archive.close();
return { filepath, contents };
});
exports.fromFile = fromFile;
/**
* Saves a valid Sketch document.
*
* @param obj - The {@link SketchFile} object to be saved.
* @returns A void Promise
*/
const toFile = (obj) => __awaiter(void 0, void 0, void 0, function* () {
yield new Promise((resolve, reject) => {
const sketch = new adm_zip_1.default();
// Write pages first and use the resulting paths for the file
// references that are stored within the main document.json.
const refs = obj.contents.document.pages.map((page) => {
const p = JSON.stringify(page);
sketch.addFile(path_1.default.join('pages', `${page.do_objectID}.json`), Buffer.alloc(Buffer.byteLength(p), p), `page data for: ${page.name}`);
return {
_class: 'MSJSONFileReference',
_ref_class: 'MSImmutablePage',
_ref: `pages/${page.do_objectID}`,
};
});
// Store workspace data
Object.keys(obj.contents.workspace).map((key) => {
const p = JSON.stringify(obj.contents.workspace[key]);
sketch.addFile(path_1.default.join('workspace', `${key}.json`), Buffer.alloc(Buffer.byteLength(p), p), `workspace data for: ${key}`);
});
const data = {
document: JSON.stringify(Object.assign(Object.assign({}, obj.contents.document), { pages: refs })),
user: JSON.stringify(obj.contents.user),
meta: JSON.stringify(obj.contents.meta),
};
Object.entries(data).map(([key, val]) => {
sketch.addFile(`${key}.json`, Buffer.alloc(Buffer.byteLength(val), val), `${key} data`);
});
sketch.writeZip(obj.filepath, (err) => {
if (err) {
reject(err);
return;
}
resolve(null);
});
});
});
exports.toFile = toFile;
;