Skip to content
This repository was archived by the owner on Jan 25, 2024. It is now read-only.

Commit fa2b961

Browse files
authored
Merge pull request #7 from kwonoj/feat-version
feat(cli): display version
2 parents 1df7a3b + 5d07778 commit fa2b961

File tree

9 files changed

+176
-6
lines changed

9 files changed

+176
-6
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"commitizen": {
1616
"path": "cz-conventional-changelog"
1717
},
18-
"libsass-version": "3.5.4-180708-3"
18+
"libsass-version": "3.5.4-180709.2"
1919
},
2020
"lint-staged": {
2121
"*.{ts,js}": [

src/SassAsmModule.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/** @internal */
2+
type stringToUTF8Signature = (str: string, outPtr: number, maxBytesToWrite: number) => void;
3+
4+
/** @internal */
5+
type cwrapSignature = <T = Function>(fn: string, returnType: string | null, parameterType: Array<string>) => T;
6+
7+
/** @internal */
8+
type FILESYSTEMS = {
9+
NODEFS: any;
10+
/* MEMFS: any; */ //libsass-asm does not support memfs, disabled
11+
};
12+
13+
/**
14+
* Subset of internal filesystem api for wasm module.
15+
*/
16+
/** @internal */
17+
type FS = {
18+
filesystems: FILESYSTEMS;
19+
stat: (path: string) => import('fs').Stats;
20+
isDir: (mode: number) => boolean;
21+
isFile: (mode: number) => boolean;
22+
mkdir: (path: string, mode?: number) => void;
23+
mount: (type: FILESYSTEMS, option: { root?: string }, mountpoint: string) => void;
24+
writeFile: (path: string, data: ArrayBufferView, opts: { encoding?: string; flags?: string }) => void;
25+
unlink: (path: string) => void;
26+
unmount: (mountpoint: string) => void;
27+
rmdir: (path: string) => void;
28+
};
29+
30+
/**
31+
* @internal
32+
*
33+
* Interface for module generated by emscripten to load wasm binary.
34+
* https://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
35+
*/
36+
interface SassAsmModule {
37+
cwrap: cwrapSignature;
38+
FS: FS;
39+
stringToUTF8: stringToUTF8Signature;
40+
stackAlloc: (length: number) => number;
41+
stackSave: () => number;
42+
stackRestore: (stack: number) => void;
43+
getValue: <T = any>(ptr: number, type: string, nosafe?: boolean) => T;
44+
Pointer_stringify: (ptr: number) => string;
45+
initializeRuntime(): Promise<boolean>;
46+
}
47+
48+
/**
49+
* @internal
50+
*
51+
* libsass functions exported via EXPORTED_FUNCTIONS,
52+
* scope: Miscellaneous(https://github.com/sass/libsass/blob/master/docs/api-doc.md#miscellaneous-api-functions)
53+
*/
54+
interface SassAsmModule {
55+
_libsass_version: () => number;
56+
_libsass_language_version: () => number;
57+
_sass2scss_version: () => number;
58+
}
59+
60+
export { stringToUTF8Signature, cwrapSignature, FILESYSTEMS, FS, SassAsmModule };

src/SassFactory.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Interface to factory object loaded via `loadModule`,
3+
* provides interop interface to libsass functions.
4+
*/
5+
interface SassFactory {
6+
getVersion: () => Promise<{
7+
libsassAsm: string;
8+
libsass: string;
9+
sassLang: string;
10+
sass2scss: string;
11+
}>;
12+
}
13+
14+
export { SassFactory };

src/ambient.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
declare module '*/lib/libsass';

src/cli.ts

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
#!/usr/bin/env node
2+
import chalk from 'chalk';
23
import * as commandLineArgs from 'command-line-args';
34

5+
/**
6+
* Supported output style. Mirrors `style_option_strings[]` in sassc
7+
* (https://github.com/sass/sassc/blob/6a64d0569205bfcf0794a473f97affcb60b22fcc/sassc.c#L184-L189)
8+
*/
49
enum StyleOption {
510
SASS_STYLE_COMPRESSED = 'compressed',
611
SASS_STYLE_COMPACT = 'compact',
712
SASS_STYLE_EXPANDED = 'expanded',
813
SASS_STYLE_NESTED = 'nested'
914
}
1015

16+
/**
17+
* Definitions of available command line args.
18+
*/
1119
const optionDefinitions = [
1220
{ name: 'stdin', alias: 's', description: 'Read input from standard input instead of an input file.' },
1321
{
@@ -22,18 +30,43 @@ const optionDefinitions = [
2230
{ name: 'omit-map-comment', alias: 'M', description: 'Omits the source map url comment.' },
2331
{ name: 'precision', alias: 'p', description: 'Set the precision for numbers.' },
2432
{ name: 'sass', alias: 'a', description: 'Treat input as indented syntax.' },
25-
{ name: 'version', alias: 'v', description: 'Display compiled versions.' },
33+
{ name: 'version', alias: 'v', description: 'Display compiled versions.', type: Boolean },
2634
{ name: 'help', alias: 'h', description: 'Display this help message.', type: Boolean }
2735
];
2836

37+
/**
38+
* Get usage definition for library version.
39+
*
40+
*/
41+
const buildDisplayVersion = async () => {
42+
const { loadModule } = await import('./loadModule');
43+
const sassFactory = await loadModule();
44+
const { libsassAsm, libsass, sassLang, sass2scss } = await sassFactory.getVersion();
45+
46+
return {
47+
header: chalk.reset('Version'),
48+
content: [
49+
{ name: 'libsass-asm', summary: libsassAsm },
50+
{ name: 'libsass', summary: libsass },
51+
{ name: 'sass', summary: sassLang },
52+
{ name: 'sass2scss', summary: sass2scss }
53+
]
54+
};
55+
};
56+
2957
(async () => {
3058
const options = commandLineArgs(optionDefinitions, { camelCase: true });
3159

32-
if (options.help || Object.keys(options).length === 0) {
33-
const commandLineUsage = await import('command-line-usage');
34-
const usage = commandLineUsage([{ header: 'Options', optionList: optionDefinitions }]);
60+
const displayHelp = options.help || Object.keys(options).length === 0;
61+
const displayVersion = options.version;
62+
63+
if (displayHelp || displayVersion) {
64+
const cmdUsage = await import('command-line-usage');
65+
const usageDefinition = displayHelp
66+
? { header: chalk.reset('Options'), optionList: optionDefinitions }
67+
: await buildDisplayVersion();
68+
const usage = cmdUsage([usageDefinition]);
3569
console.log(usage);
36-
} else if (options.version) {
3770
return;
3871
}
3972
})();

src/interop/miscellaneous.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { SassAsmModule } from '../SassAsmModule';
2+
3+
/**
4+
* Creates function to read versions of library.
5+
* @param asmModule
6+
*/
7+
const getVersion = (asmModule: SassAsmModule) => async () => {
8+
const { stackSave, stackRestore, Pointer_stringify } = asmModule;
9+
//version functions doesn't need param type conversion, call directly without cwrap
10+
const { _libsass_version, _libsass_language_version, _sass2scss_version } = asmModule;
11+
12+
const { version } = await import('../../package.json');
13+
const stack = stackSave();
14+
const ret = {
15+
libsassAsm: version,
16+
libsass: Pointer_stringify(_libsass_version()),
17+
sassLang: Pointer_stringify(_libsass_language_version()),
18+
sass2scss: Pointer_stringify(_sass2scss_version())
19+
};
20+
stackRestore(stack);
21+
return ret;
22+
};
23+
24+
export { getVersion };

src/loadModule.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { getModuleLoader } from 'emscripten-wasm-loader';
2+
import { SassAsmModule } from './SassAsmModule';
3+
import { SassFactory } from './SassFactory';
4+
import { sassLoader } from './sassLoader';
5+
import { log } from './util/logger';
6+
7+
/**
8+
* Load, initialize wasm binary to use actual sass instance.
9+
*
10+
* @returns {Promise<SassFactory>} Function to load module
11+
*/
12+
const loadModule = async (): Promise<SassFactory> => {
13+
log(`loadModule: loading libsass module`);
14+
15+
//imports MODULARIZED emscripten preamble
16+
const runtimeModule = await import('./lib/libsass');
17+
const moduleLoader = await getModuleLoader<SassFactory, SassAsmModule>(sassLoader, runtimeModule);
18+
19+
return moduleLoader();
20+
};
21+
22+
export { loadModule };

src/sassLoader.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { getVersion } from './interop/miscellaneous';
2+
import { SassAsmModule } from './SassAsmModule';
3+
import { SassFactory } from './SassFactory';
4+
5+
/**
6+
* Create SassFactory interface object through loaded libass wasm module.
7+
*
8+
* @param {SassAsmModule} asmModule wasm module
9+
* @returns {SassFactory}
10+
*/
11+
export const sassLoader = (asmModule: SassAsmModule): SassFactory => {
12+
return {
13+
getVersion: getVersion(asmModule)
14+
};
15+
};

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"importHelpers": true,
1717
"pretty": true,
1818
"target": "es2017",
19+
"resolveJsonModule": true,
1920
"outDir": "dist",
2021
"lib": [
2122
"es5",

0 commit comments

Comments
 (0)