pax_global_header00006660000000000000000000000064131105036500014504gustar00rootroot0000000000000052 comment=7f4028cdd764aaa7a1b458567fe1febe555cdcd7 postcss-modules-extract-imports-1.2.0/000077500000000000000000000000001311050365000200135ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/.eslintrc000066400000000000000000000007501311050365000216410ustar00rootroot00000000000000{ "parser": "babel-eslint", "env": { "node": true }, "ecmaFeatures": { "arrowFunctions": true, "blockBindings": true, "classes": true, "defaultParams": true, "destructuring": true, "forOf": true, "modules": true, "objectLiteralComputedProperties": true, "objectLiteralShorthandMethods": true, "objectLiteralShorthandProperties": true, "spread": true, "superInFunctions": true, "templateStrings": true, "unicodeCodePointEscapes": true, "jsx": true } } postcss-modules-extract-imports-1.2.0/.gitignore000066400000000000000000000000561311050365000220040ustar00rootroot00000000000000.DS_Store coverage lib node_modules yarn.lock postcss-modules-extract-imports-1.2.0/.travis.yml000066400000000000000000000004051311050365000221230ustar00rootroot00000000000000language: node_js node_js: - "4" - "6" - "node" script: npm run travis after_success: - cat ./coverage/lcov.info | node_modules/.bin/coveralls --verbose - cat ./coverage/coverage.json | node_modules/codecov.io/bin/codecov.io.js - rm -rf ./coverage postcss-modules-extract-imports-1.2.0/README.md000066400000000000000000000031271311050365000212750ustar00rootroot00000000000000# CSS Modules: Extract Imports [![Build Status](https://travis-ci.org/css-modules/postcss-modules-extract-imports.svg?branch=master)](https://travis-ci.org/css-modules/postcss-modules-extract-imports) Transforms: ```css :local(.continueButton) { composes: button from "library/button.css"; color: green; } ``` into: ```css :import("library/button.css") { button: __tmp_487387465fczSDGHSABb; } :local(.continueButton) { composes: __tmp_487387465fczSDGHSABb; color: green; } ``` ## Specification - Only a certain whitelist of properties are inspected. Currently, that whitelist is `['composes']` alone. - An extend-import has the following format: ``` composes: className [... className] from "path/to/file.css"; ``` ## Building ``` npm install npm build npm test ``` [![Build Status](https://travis-ci.org/css-modules/postcss-modules-extract-imports.svg?branch=master)](https://travis-ci.org/css-modules/postcss-modules-extract-imports) * Lines: [![Coverage Status](https://coveralls.io/repos/css-modules/postcss-modules-extract-imports/badge.svg?branch=master)](https://coveralls.io/r/css-modules/postcss-modules-extract-imports?branch=master) * Statements: [![codecov.io](http://codecov.io/github/css-modules/postcss-modules-extract-imports/coverage.svg?branch=master)](http://codecov.io/github/css-modules/postcss-modules-extract-imports?branch=master) ## Development - `npm watch` will watch `src` for changes and rebuild - `npm autotest` will watch `src` and `test` for changes and retest ## License ISC ## With thanks - Mark Dalgleish - Tobias Koppers - Guy Bedford --- Glen Maddern, 2015. postcss-modules-extract-imports-1.2.0/package.json000066400000000000000000000026301311050365000223020ustar00rootroot00000000000000{ "name": "postcss-modules-extract-imports", "version": "1.2.0", "description": "A CSS Modules transform to extract local aliases for inline imports", "main": "lib/index.js", "scripts": { "lint": "eslint src", "build": "babel --out-dir lib src", "watch": "chokidar src -c 'npm run build'", "posttest": "npm run lint && npm run build", "test": "mocha --compilers js:babel/register", "autotest": "chokidar src test -c 'npm test'", "precover": "npm run lint && npm run build", "cover": "babel-istanbul cover node_modules/.bin/_mocha", "travis": "npm run cover -- --report lcovonly", "prepublish": "npm run build" }, "repository": { "type": "git", "url": "https://github.com/css-modules/postcss-modules-extract-imports.git" }, "keywords": [ "css-modules", "postcss", "plugin" ], "files": [ "lib" ], "author": "Glen Maddern", "license": "ISC", "bugs": { "url": "https://github.com/css-modules/postcss-modules-extract-imports/issues" }, "homepage": "https://github.com/css-modules/postcss-modules-extract-imports", "dependencies": { "postcss": "^6.0.1" }, "devDependencies": { "babel": "^5.4.7", "babel-eslint": "^7.2.2", "babel-istanbul": "^0.4.0", "babelify": "^7.3.0", "chokidar-cli": "^1.0.1", "codecov.io": "^0.1.2", "coveralls": "^2.11.2", "eslint": "^1.5.0", "mocha": "^3.1.2" } } postcss-modules-extract-imports-1.2.0/src/000077500000000000000000000000001311050365000206025ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/src/index.js000066400000000000000000000111331311050365000222460ustar00rootroot00000000000000import postcss from 'postcss'; import topologicalSort from './topologicalSort'; const declWhitelist = ['composes']; const declFilter = new RegExp( `^(${declWhitelist.join( '|' )})$` ); const matchImports = /^(.+?)\s+from\s+(?:"([^"]+)"|'([^']+)'|(global))$/; const icssImport = /^:import\((?:"([^"]+)"|'([^']+)')\)/; const VISITED_MARKER = 1; function createParentName(rule, root) { return `__${root.index(rule.parent)}_${rule.selector}`; } function serializeImports(imports) { return imports.map(importPath => '`' + importPath + '`').join(', '); } /** * :import('G') {} * * Rule * composes: ... from 'A' * composes: ... from 'B' * Rule * composes: ... from 'A' * composes: ... from 'A' * composes: ... from 'C' * * Results in: * * graph: { * G: [], * A: [], * B: ['A'], * C: ['A'], * } */ function addImportToGraph(importId, parentId, graph, visited) { const siblingsId = parentId + '_' + 'siblings'; const visitedId = parentId + '_' + importId; if (visited[visitedId] !== VISITED_MARKER) { if (!Array.isArray(visited[siblingsId])) visited[siblingsId] = []; const siblings = visited[siblingsId]; if (Array.isArray(graph[importId])) graph[importId] = graph[importId].concat(siblings); else graph[importId] = siblings.slice(); visited[visitedId] = VISITED_MARKER; siblings.push(importId); } } const processor = postcss.plugin('modules-extract-imports', function (options = {}) { const failOnWrongOrder = options.failOnWrongOrder; return css => { const graph = {}; const visited = {}; const existingImports = {}; const importDecls = {}; const imports = {}; let importIndex = 0; const createImportedName = typeof options.createImportedName !== 'function' ? (importName/*, path*/) => `i__imported_${importName.replace(/\W/g, '_')}_${importIndex++}` : options.createImportedName; // Check the existing imports order and save refs css.walkRules(rule => { const matches = icssImport.exec(rule.selector); if (matches) { const [/*match*/, doubleQuotePath, singleQuotePath] = matches; const importPath = doubleQuotePath || singleQuotePath; addImportToGraph(importPath, 'root', graph, visited); existingImports[importPath] = rule; } }); // Find any declaration that supports imports css.walkDecls(declFilter, decl => { let matches = decl.value.match(matchImports); let tmpSymbols; if (matches) { let [/*match*/, symbols, doubleQuotePath, singleQuotePath, global] = matches; if (global) { // Composing globals simply means changing these classes to wrap them in global(name) tmpSymbols = symbols.split(/\s+/).map(s => `global(${s})`); } else { const importPath = doubleQuotePath || singleQuotePath; const parentRule = createParentName(decl.parent, css); addImportToGraph(importPath, parentRule, graph, visited); importDecls[importPath] = decl; imports[importPath] = imports[importPath] || {}; tmpSymbols = symbols.split(/\s+/).map(s => { if (!imports[importPath][s]) { imports[importPath][s] = createImportedName(s, importPath); } return imports[importPath][s]; }); } decl.value = tmpSymbols.join(' '); } }); const importsOrder = topologicalSort(graph, failOnWrongOrder); if (importsOrder instanceof Error) { const importPath = importsOrder.nodes.find(importPath => importDecls.hasOwnProperty(importPath)); const decl = importDecls[importPath]; const errMsg = 'Failed to resolve order of composed modules ' + serializeImports(importsOrder.nodes) + '.'; throw decl.error(errMsg, { plugin: 'modules-extract-imports', word: 'composes', }); } let lastImportRule; importsOrder.forEach(path => { const importedSymbols = imports[path]; let rule = existingImports[path]; if (!rule && importedSymbols) { rule = postcss.rule({ selector: `:import("${path}")`, raws: {after: '\n'}, }); if (lastImportRule) css.insertAfter(lastImportRule, rule); else css.prepend(rule); } lastImportRule = rule; if (!importedSymbols) return; Object.keys(importedSymbols).forEach(importedSymbol => { rule.append(postcss.decl({ value: importedSymbol, prop: importedSymbols[importedSymbol], raws: {before: '\n '}, })); }); }); }; }); export default processor; postcss-modules-extract-imports-1.2.0/src/topologicalSort.js000066400000000000000000000022421311050365000243240ustar00rootroot00000000000000const PERMANENT_MARKER = 2; const TEMPORARY_MARKER = 1; function createError(node, graph) { const er = new Error('Nondeterministic import\'s order'); const related = graph[node]; const relatedNode = related.find(relatedNode => graph[relatedNode].indexOf(node) > -1); er.nodes = [node, relatedNode]; return er; } function walkGraph(node, graph, state, result, strict) { if (state[node] === PERMANENT_MARKER) return; if (state[node] === TEMPORARY_MARKER) { if (strict) return createError(node, graph); return; } state[node] = TEMPORARY_MARKER; const children = graph[node]; const length = children.length; for (let i = 0; i < length; ++i) { const er = walkGraph(children[i], graph, state, result, strict); if (er instanceof Error) return er; } state[node] = PERMANENT_MARKER; result.push(node); } export default function topologicalSort(graph, strict) { const result = []; const state = {}; const nodes = Object.keys(graph); const length = nodes.length; for (let i = 0; i < length; ++i) { const er = walkGraph(nodes[i], graph, state, result, strict); if (er instanceof Error) return er; } return result; } postcss-modules-extract-imports-1.2.0/test/000077500000000000000000000000001311050365000207725ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/check-import-order.js000066400000000000000000000012141311050365000250240ustar00rootroot00000000000000'use strict'; const assert = require('assert'); const postcss = require('postcss'); const processor = require('../'); describe('check-import-order', () => { let pipeline; beforeEach(() => { pipeline = postcss([ processor({failOnWrongOrder: true}), ]); }); it('should throw an exception', () => { const input = ` .aa { composes: b from './b.css'; composes: c from './c.css'; } .bb { composes: c from './c.css'; composes: b from './b.css'; } `; assert.throws(() => pipeline.process(input).css, /Failed to resolve order of composed modules/); }); }); postcss-modules-extract-imports-1.2.0/test/custom-import-name.js000066400000000000000000000011761311050365000250750ustar00rootroot00000000000000"use strict"; /*globals describe it */ var assert = require("assert"); var postcss = require("postcss"); var processor = require("../"); describe("custom-import-name", function() { it("should allow to provide a custom imported name", function() { var input = ":local(.name) { composes: abc from \"def\"; }"; var expected = ":import(\"def\") {\n abc-from-def: abc;\n}\n:local(.name) { composes: abc-from-def; }"; var pipeline = postcss([processor({ createImportedName: function(importName, path) { return importName + "-from-" + path; } })]); assert.equal(pipeline.process(input).css, expected); }); }); postcss-modules-extract-imports-1.2.0/test/test-cases.js000066400000000000000000000015661311050365000234130ustar00rootroot00000000000000"use strict"; /*globals describe it */ var assert = require("assert"); var fs = require("fs"); var path = require("path"); var postcss = require("postcss"); var processor = require("../src"); var pipeline = postcss([processor]); function normalize(str) { return str.replace(/\r\n?/g, "\n").replace(/\n$/,''); } describe("test-cases", function() { var testDir = path.join(__dirname, "test-cases"); fs.readdirSync(testDir).forEach(function(testCase) { if(fs.existsSync(path.join(testDir, testCase, "source.css"))) { it("should " + testCase.replace(/-/g, " "), function() { var input = normalize(fs.readFileSync(path.join(testDir, testCase, "source.css"), "utf-8")); var expected = normalize(fs.readFileSync(path.join(testDir, testCase, "expected.css"), "utf-8")); assert.equal(pipeline.process(input).css, expected); }); } }); }); postcss-modules-extract-imports-1.2.0/test/test-cases/000077500000000000000000000000001311050365000230455ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/composing-globals/000077500000000000000000000000001311050365000264645ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/composing-globals/expected.css000066400000000000000000000001301311050365000307710ustar00rootroot00000000000000:local(.exportName) { composes: global(importName) global(secondImport); other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/composing-globals/source.css000066400000000000000000000001241311050365000304730ustar00rootroot00000000000000:local(.exportName) { composes: importName secondImport from global; other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/existing-import/000077500000000000000000000000001311050365000262075ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/existing-import/expected.css000066400000000000000000000002321311050365000305170ustar00rootroot00000000000000:import("path/library.css") { something: else; i__imported_importName_0: importName; } :local(.exportName) { composes: i__imported_importName_0; } postcss-modules-extract-imports-1.2.0/test/test-cases/existing-import/source.css000066400000000000000000000001741311050365000302230ustar00rootroot00000000000000:import("path/library.css") { something: else; } :local(.exportName) { composes: importName from 'path/library.css'; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-comment/000077500000000000000000000000001311050365000260175ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/import-comment/expected.css000066400000000000000000000001351311050365000303310ustar00rootroot00000000000000/* :local(.exportName) { composes: importName from "path/library.css"; other: rule; } */ postcss-modules-extract-imports-1.2.0/test/test-cases/import-comment/source.css000066400000000000000000000001351311050365000300300ustar00rootroot00000000000000/* :local(.exportName) { composes: importName from "path/library.css"; other: rule; } */ postcss-modules-extract-imports-1.2.0/test/test-cases/import-consolidate/000077500000000000000000000000001311050365000266615ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/import-consolidate/expected.css000066400000000000000000000007021311050365000311730ustar00rootroot00000000000000:import("path/library.css") { i__imported_importName_0: importName; i__imported_secondImport_1: secondImport; i__imported_thirdImport_2: thirdImport; } :import("path/other-lib.css") { i__imported_otherLibImport_3: otherLibImport; } :local(.exportName) { composes: i__imported_importName_0 i__imported_secondImport_1; other: rule; } :local(.otherExport) { composes: i__imported_thirdImport_2; composes: i__imported_otherLibImport_3; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-consolidate/source.css000066400000000000000000000003451311050365000306750ustar00rootroot00000000000000 :local(.exportName) { composes: importName secondImport from 'path/library.css'; other: rule; } :local(.otherExport) { composes: thirdImport from 'path/library.css'; composes: otherLibImport from 'path/other-lib.css'; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-local-extends/000077500000000000000000000000001311050365000271175ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/import-local-extends/expected.css000066400000000000000000000000761311050365000314350ustar00rootroot00000000000000:local(.exportName) { composes: localName; other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-local-extends/source.css000066400000000000000000000000761311050365000311340ustar00rootroot00000000000000:local(.exportName) { composes: localName; other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-media/000077500000000000000000000000001311050365000254345ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/import-media/expected.css000066400000000000000000000005221311050365000277460ustar00rootroot00000000000000:import("path/library.css") { i__imported_importName_0: importName; i__imported_importName2_1: importName2; } @media screen { :local(.exportName) { composes: i__imported_importName_0; composes: i__imported_importName2_1; other: rule2; } } :local(.exportName) { composes: i__imported_importName_0; other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-media/source.css000066400000000000000000000003751311050365000274530ustar00rootroot00000000000000@media screen { :local(.exportName) { composes: importName from "path/library.css"; composes: importName2 from "path/library.css"; other: rule2; } } :local(.exportName) { composes: importName from "path/library.css"; other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-multiple-classes/000077500000000000000000000000001311050365000276435ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/import-multiple-classes/expected.css000066400000000000000000000003301311050365000321520ustar00rootroot00000000000000:import("path/library.css") { i__imported_importName_0: importName; i__imported_secondImport_1: secondImport; } :local(.exportName) { composes: i__imported_importName_0 i__imported_secondImport_1; other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-multiple-classes/source.css000066400000000000000000000001401311050365000316500ustar00rootroot00000000000000:local(.exportName) { composes: importName secondImport from 'path/library.css'; other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-multiple-references/000077500000000000000000000000001311050365000303275ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/import-multiple-references/expected.css000066400000000000000000000011331311050365000326400ustar00rootroot00000000000000:import("path/library.css") { i__imported_importName_0: importName; i__imported_secondImport_1: secondImport; i__imported_importName2_3: importName2; } :import("path/library2.css") { i__imported_importName_2: importName; } :import("path/dep3.css") { i__imported_thirdDep_4: thirdDep; } :local(.exportName) { composes: i__imported_importName_0 i__imported_secondImport_1; composes: i__imported_importName_2; composes: i__imported_importName2_3; } :local(.exportName2) { composes: i__imported_secondImport_1; composes: i__imported_secondImport_1; composes: i__imported_thirdDep_4; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-multiple-references/source.css000066400000000000000000000005371311050365000323460ustar00rootroot00000000000000:local(.exportName) { composes: importName secondImport from 'path/library.css'; composes: importName from 'path/library2.css'; composes: importName2 from 'path/library.css'; } :local(.exportName2) { composes: secondImport from 'path/library.css'; composes: secondImport from 'path/library.css'; composes: thirdDep from 'path/dep3.css'; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-only-whitelist/000077500000000000000000000000001311050365000273505ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/import-only-whitelist/expected.css000066400000000000000000000001761311050365000316670ustar00rootroot00000000000000:local(.exportName) { imports: importName from "path/library.css"; something-else: otherLibImport from "path/other-lib.css"; }postcss-modules-extract-imports-1.2.0/test/test-cases/import-only-whitelist/source.css000066400000000000000000000001761311050365000313660ustar00rootroot00000000000000:local(.exportName) { imports: importName from "path/library.css"; something-else: otherLibImport from "path/other-lib.css"; }postcss-modules-extract-imports-1.2.0/test/test-cases/import-preserving-order/000077500000000000000000000000001311050365000276525ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/import-preserving-order/expected.css000066400000000000000000000002521311050365000321640ustar00rootroot00000000000000:import("./b.css") { i__imported_b_0: b; } :import("./c.css") { i__imported_c_1: c; } .a { composes: i__imported_b_0; composes: i__imported_c_1; color: #aaa; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-preserving-order/source.css000066400000000000000000000001221311050365000316570ustar00rootroot00000000000000.a { composes: b from "./b.css"; composes: c from "./c.css"; color: #aaa; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-single-quotes/000077500000000000000000000000001311050365000271545ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/import-single-quotes/expected.css000066400000000000000000000002251311050365000314660ustar00rootroot00000000000000:import("path/library.css") { i__imported_importName_0: importName; } :local(.exportName) { composes: i__imported_importName_0; other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-single-quotes/source.css000066400000000000000000000001271311050365000311660ustar00rootroot00000000000000:local(.exportName) { composes: importName from 'path/library.css'; other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-spacing/000077500000000000000000000000001311050365000260015ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/import-spacing/expected.css000066400000000000000000000004461311050365000303200ustar00rootroot00000000000000:import("path/library.css") { i__imported_importName_0: importName; i__imported_importName2_1: importName2; } :local(.exportName) { composes: i__imported_importName_0; composes: i__imported_importName2_1; composes: i__imported_importName_0 i__imported_importName2_1; other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-spacing/source.css000066400000000000000000000003211311050365000300070ustar00rootroot00000000000000:local(.exportName) { composes: importName from "path/library.css"; composes: importName2 from "path/library.css"; composes: importName importName2 from "path/library.css"; other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-within/000077500000000000000000000000001311050365000256575ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/import-within/expected.css000066400000000000000000000002251311050365000301710ustar00rootroot00000000000000:import("path/library.css") { i__imported_importName_0: importName; } :local(.exportName) { composes: i__imported_importName_0; other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/import-within/source.css000066400000000000000000000001271311050365000276710ustar00rootroot00000000000000:local(.exportName) { composes: importName from "path/library.css"; other: rule; } postcss-modules-extract-imports-1.2.0/test/test-cases/resolve-composes-order/000077500000000000000000000000001311050365000274635ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/resolve-composes-order/expected.css000066400000000000000000000004031311050365000317730ustar00rootroot00000000000000:import("./b.css") { i__imported_b_1: b; } :import("./c.css") { i__imported_c_0: c; } .a { composes: i__imported_c_0; color: #bebebe; } .b { /* `b` should be after `c` */ composes: i__imported_b_1; composes: i__imported_c_0; color: #aaa; } postcss-modules-extract-imports-1.2.0/test/test-cases/resolve-composes-order/source.css000066400000000000000000000002521311050365000314740ustar00rootroot00000000000000.a { composes: c from "./c.css"; color: #bebebe; } .b { /* `b` should be after `c` */ composes: b from "./b.css"; composes: c from "./c.css"; color: #aaa; } postcss-modules-extract-imports-1.2.0/test/test-cases/resolve-duplicates/000077500000000000000000000000001311050365000266575ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/resolve-duplicates/expected.css000066400000000000000000000004731311050365000311760ustar00rootroot00000000000000:import("./aa.css") { i__imported_a_0: a; } :import("./bb.css") { i__imported_b_1: b; } :import("./cc.css") { smthing: somevalue; i__imported_c_2: c; } .a { composes: i__imported_a_0; composes: i__imported_b_1; composes: i__imported_c_2; composes: i__imported_a_0; composes: i__imported_c_2; } postcss-modules-extract-imports-1.2.0/test/test-cases/resolve-duplicates/source.css000066400000000000000000000003211311050365000306650ustar00rootroot00000000000000:import("./cc.css") { smthing: somevalue; } .a { composes: a from './aa.css'; composes: b from './bb.css'; composes: c from './cc.css'; composes: a from './aa.css'; composes: c from './cc.css'; } postcss-modules-extract-imports-1.2.0/test/test-cases/resolve-imports-order/000077500000000000000000000000001311050365000273305ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/resolve-imports-order/expected.css000066400000000000000000000012151311050365000316420ustar00rootroot00000000000000:import("custom-path.css") { /* empty to check the order */ } :import("./cc.css") { i__imported_cc_3: cc; i__imported_dd_5: dd; } :import("./bb.css") { somevalue: localvalue; i__imported_bb_1: bb; i__imported_dd_6: dd; } :import("./aa.css") { i__imported_aa_0: aa; i__imported_bb_2: bb; i__imported_cc_4: cc; } :import("./dd.css") { i__imported_dd_7: dd; } .a { composes: i__imported_aa_0; } .b { composes: i__imported_bb_1; composes: i__imported_bb_2; } .c { composes: i__imported_cc_3; composes: i__imported_cc_4; } .d { composes: i__imported_dd_5; composes: i__imported_dd_6; composes: i__imported_dd_7; } postcss-modules-extract-imports-1.2.0/test/test-cases/resolve-imports-order/source.css000066400000000000000000000006221311050365000313420ustar00rootroot00000000000000:import("custom-path.css") { /* empty to check the order */ } :import("./bb.css") { somevalue: localvalue; } .a { composes: aa from './aa.css'; } .b { composes: bb from './bb.css'; composes: bb from './aa.css'; } .c { composes: cc from './cc.css'; composes: cc from './aa.css'; } .d { composes: dd from './cc.css'; composes: dd from './bb.css'; composes: dd from './dd.css'; } postcss-modules-extract-imports-1.2.0/test/test-cases/valid-characters/000077500000000000000000000000001311050365000262615ustar00rootroot00000000000000postcss-modules-extract-imports-1.2.0/test/test-cases/valid-characters/expected.css000066400000000000000000000007011311050365000305720ustar00rootroot00000000000000:import("path/library.css") { i__imported_a_0: a; i__imported__b_1: -b; i__imported___c_2: --c; i__imported__d_3: _d; } :import("path/library2.css") { i__imported_a__4: a_; i__imported_b__5: b-; i__imported_c___6: c--; i__imported_d___7: d\%; } :local(.exportName) { composes: i__imported_a_0 i__imported__b_1 i__imported___c_2 i__imported__d_3; composes: i__imported_a__4 i__imported_b__5 i__imported_c___6 i__imported_d___7; } postcss-modules-extract-imports-1.2.0/test/test-cases/valid-characters/source.css000066400000000000000000000001751311050365000302760ustar00rootroot00000000000000:local(.exportName) { composes: a -b --c _d from "path/library.css"; composes: a_ b- c-- d\% from "path/library2.css"; } postcss-modules-extract-imports-1.2.0/test/topologicalSort.js000066400000000000000000000022211311050365000245110ustar00rootroot00000000000000'use strict'; const assert = require('assert'); const topologicalSort = require('../src/topologicalSort'); const STRICT = true; describe('topologicalSort', () => { it('should resolve graphs', () => { const graph1 = { v1: ['v2', 'v5'], v2: [], v3: ['v2', 'v4', 'v5'], v4: [], v5: [], }; const graph2 = { v1: ['v2', 'v5'], v2: ['v4'], v3: ['v2', 'v4', 'v5'], v4: [], v5: [], }; assert.deepEqual(topologicalSort(graph1, STRICT), ['v2', 'v5', 'v1', 'v4', 'v3']); assert.deepEqual(topologicalSort(graph2, STRICT), ['v4', 'v2', 'v5', 'v1', 'v3']); }); it('should return exception if there is a cycle in the graph', () => { const graph = { v1: ['v3'], v2: [], v3: ['v1'], }; const er = topologicalSort(graph, STRICT); assert.ok(er instanceof Error, 'Expected exception'); assert.deepEqual(er.nodes, ['v1', 'v3']); }); it('should resolve graph in non-strict mode', () => { const graph = { v1: ['v3'], v2: [], v3: ['v1'], }; assert.deepEqual(topologicalSort(graph, !STRICT), ['v3', 'v1', 'v2']); }); });