Coder Social home page Coder Social logo

ts-transformer-keys's Introduction

ts-transformer-keys

A TypeScript custom transformer which enables to obtain keys of given type.

Build Status NPM version Downloads

Requirement

TypeScript >= 2.4.1

How to use this package

This package exports 2 functions. One is keys which is used in TypeScript codes to obtain keys of given type, while the other is a TypeScript custom transformer which is used to compile the keys function correctly.

How to use keys

import { keys } from 'ts-transformer-keys';

interface Props {
  id: string;
  name: string;
  age: number;
}
const keysOfProps = keys<Props>();

console.log(keysOfProps); // ['id', 'name', 'age']

How to use the custom transformer

Unfortunately, TypeScript itself does not currently provide any easy way to use custom transformers (See microsoft/TypeScript#14419). The followings are the example usage of the custom transformer.

webpack (with ts-loader or awesome-typescript-loader)

See examples/webpack for detail.

// webpack.config.js
const keysTransformer = require('ts-transformer-keys/transformer').default;

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: 'ts-loader', // or 'awesome-typescript-loader'
        options: {
          // make sure not to set `transpileOnly: true` here, otherwise it will not work
          getCustomTransformers: program => ({
              before: [
                  keysTransformer(program)
              ]
          })
        }
      }
    ]
  }
};

Rollup (with rollup-plugin-typescript2)

See examples/rollup for detail.

// rollup.config.js
import resolve from 'rollup-plugin-node-resolve';
import typescript from 'rollup-plugin-typescript2';
import keysTransformer from 'ts-transformer-keys/transformer';

export default {
  // ...
  plugins: [
    resolve(),
    typescript({ transformers: [service => ({
      before: [ keysTransformer(service.getProgram()) ],
      after: []
    })] })
  ]
};

ttypescript

See examples/ttypescript for detail. See ttypescript's README for how to use this with module bundlers such as webpack or Rollup.

// tsconfig.json
{
  "compilerOptions": {
    // ...
    "plugins": [
      { "transform": "ts-transformer-keys/transformer" }
    ]
  },
  // ...
}

ts-jest

See examples/ts-jest for details. In order to use this transformer with ts-jest, you need to add a wrapper around it like this:

// ts-jest-keys-transformer.js
const keysTransformer = require('ts-transformer-keys/transformer').default;
const name = 'my-key-transformer';
const version = 1;
const factory = (cs) => (ctx) => keysTransformer(cs.program)(ctx);
// For ts-jest 26 use:
// const factory = (cs) => (ctx) => keysTransformer(cs.tsCompiler.program)(ctx);

module.exports = { name, version, factory };

And add it in jest.config.js like this:

  globals: {
    'ts-jest': {
      // relative path to the ts-jest-keys-transformer.js file
      astTransformers: { before: ['src/react/ts-jest-keys-transformer.js'] },
    },
  },

Note: ts-jest 26.4.2 does not work with this transformer (fixed in ts-jest 26.4.3). Also, for versions smaller than 26.2, you need to provide the transformer in an array instead, like this: astTransformers: { before: ['src/react/ts-jest-keys-transformer.js'] }

TypeScript API

See test for detail. You can try it with $ npm test.

const ts = require('typescript');
const keysTransformer = require('ts-transformer-keys/transformer').default;

const program = ts.createProgram([/* your files to compile */], {
  strict: true,
  noEmitOnError: true,
  target: ts.ScriptTarget.ES5
});

const transformers = {
  before: [keysTransformer(program)],
  after: []
};
const { emitSkipped, diagnostics } = program.emit(undefined, undefined, undefined, false, transformers);

if (emitSkipped) {
  throw new Error(diagnostics.map(diagnostic => diagnostic.messageText).join('\n'));
}

As a result, the TypeScript code shown here is compiled into the following JavaScript.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ts_transformer_keys_1 = require("ts-transformer-keys");
var keysOfProps = ["id", "name", "age"];
console.log(keysOfProps); // ['id', 'name', 'age']

Note

  • The keys function can only be used as a call expression. Writing something like keys.toString() results in a runtime error.
  • keys does not work with a dynamic type parameter, i.e., keys<T>() in the following code is converted to an empty array([]).
class MyClass<T extends object> {
  keys() {
    return keys<T>();
  }
}

License

MIT

ts-transformer-keys's People

Contributors

carsonf avatar dcermak avatar dependabot[bot] avatar hcanber avatar kimamula avatar mhienle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ts-transformer-keys's Issues

Program is undefined

I'm unable to get a successful webpack production-level React bundle after integrating this plugin. Below is my ts-loader module rule:

const keysTransformer = require('ts-transformer-keys/transformer').default;
// more webpack config 
module: {
    rules: [
// more rules related to JS and image files
		{
			test: /\.(ts|tsx)$/,
			include: paths.appSrc,
			use: [
			  {
				loader: require.resolve('ts-loader'),
				options: {
				  // disable type checker - we will use it in fork plugin
				  transpileOnly: true,
				  configFile: paths.appTsConfig,
				  getCustomTransformers: (program) => ({
					before: [keysTransformer(program)]
				  })
				},
			  },
			],
		}
    ]
}

Upon building, I receive the following error:

Module build failed: TypeError: Cannot read property 'getTypeChecker' of undefined

Looking at the transformer code, it looks like this is due to the program passed into the transformer being undefined. Current versions of related packages are:

  • typescript: 2.9.2
  • ts-loader: 2.3.7
  • ts-transformer-keys: 0.3.5

I inspected the ts-loader README but didn't see any indication as to why program would be undefined. Has anyone else seen this issue? Am I missing a configuration? Any help is appreciated.

This may not be entirely related to this package. If not, let me know and I'll move this issue to ts-loader.

windows, index.ts path slash unmatch

const indexTs = declaration.getSourceFile().fileName
// indexTs == D:/path/to/node_modules/ts-transformer-keys/index.ts

const indexTs = path.join(__dirname, 'index.ts');
// indexTs == D:\path\to\node_modules\ts-transformer-keys\index.ts

Goes against TypeScript Design Goals?

Interesting project! However, according to the TypeScript design goals, it seems that having the type system "leak" into runtime would go against the goal of a "fully erasable type system."

I don't intend to just be a naysayer! I want to know more about the thinking behind this project and what it solves that can't be solved in TypeScript as it stands today.

ts_transformer_keys_1.keys is not a function

Hi there!

This package sounds like the ideal solution to a problem I have but I am struggling to get past the following error: "TypeError: ts_transformer_keys_1.keys is not a function" and I am not sure how to tell if this is an error on my part or if there is something out of my control that is not working.

I have tried compiling the following file with typescript 2.4.0 and running in the browser with no other packages:

import { keys } from "ts-transformer-keys";

interface Props {
    id: string;
    name: string;
    age: number;
}
const keysOfProps = keys<Props>();

console.log(keysOfProps); 

I have also tried using ts-node and executing the same file from the command line, though here in particular I am unsure to what extend ts-node is a bottleneck.

I hope I'm missing something super simple!

Thanks in advance for any thoughts in any direction!

Keys transformer includes `never` typed keys

TLDR: A property declared stuff: never gets included in the keyed output. I imagine this goes against most use cases of the transformer.

Example

Input:

import { keys } from "ts-transformer-keys";

interface Stuff {
    a: string;
    b: never;
};

const STUFF_FIELDS = keys<Stuff>();

Output:

;
const STUFF_FIELDS = ["a", "b"];
export {};
//# sourceMappingURL=ts-transformer-never.mjs.map

Notice how both a and b are present in the generated code. That's in contrast to any actual object compliant with the interface, that will never have a field named b.

Workaround

There's no utility type (in TS 5 at least) that does the filtering for us.
One can however construct such type:

type OmitNever<T> = { [K in keyof T as T[K] extends never ? never : K]: T[K] }

(cc https://stackoverflow.com/a/69852402).

Above example, with OmitNever:

import { keys } from "ts-transformer-keys";

interface Stuff {
    a: string;
    b: never;
};

const STUFF_FIELDS = keys<Stuff>();

type OmitNever<T> = { [K in keyof T as T[K] extends never ? never : K]: T[K] }
const STUFF_FIELDS_EXPECTED = keys<OmitNever<Stuff>>();

Output:

;
const STUFF_FIELDS = ["a", "b"];
const STUFF_FIELDS_EXPECTED = ["a"];
export {};
//# sourceMappingURL=ts-transformer-never.mjs.map

Footnote

An extended version of OmitNever may be necessary to support declarations like c?: never:

type OmitNever<T> = { [K in keyof T as T[K] extends never|undefined ? never : K]: T[K] }

Detected in

Node 20.7.0 + TS 5.2 + ts-patch 3.0.2 + ts-transformer-keys 0.4.4 + Transpilation to ESM

Calling instance method from getter in VueSingleFileComponent causes error: Cannot find module

I've a vue 3 project with typescript and I'm trying to get ts-transformer-keys work.

My configuration:

tsconfig.json:

"plugins": [
      { "transform": "ts-transformer-keys/transformer" }
]

vue.config.js

chainWebpack: config => {
    ['ts', 'tsx'].forEach(rule => {
      config.module
        .rule(rule)
        .use('ts-loader')
        .tap(options => Object.assign(options, {
          compiler: 'ttypescript',
          transpileOnly: false
        }))
    })
  }

I could locate the issue in the following problem:
If I call an instance method from a getter I got an error

Error: Cannot find module 'C:\path\src\App.vue.ts'

Without ts-transformer-keys this works fine.

For Example:
App.vue:

<template>
  <p>{{ message }}</p>
  <p>{{ messageAlias }}</p>
  <p>{{ upperCaseMessage }}</p>
  <p>{{ messageToUpperCase }}</p>
</template>

<script lang="ts">
import { Vue } from 'vue-class-component'
export default class App extends Vue {
  message = 'hello World'

  get messageAlias() {
    return this.message
  }

  get upperCaseMessage() {
    // return this.message.toUpperCase() // this will work
    return this.messageToUpperCase() // this won't
  }

  messageToUpperCase() {
    return this.message.toUpperCase()
  }
}
</script>

Any option to handle union types ?

Question.
Supposing I have a string literal union type, is there a way to generate its strings ?

type X = "A" | "B" | "C";

// generate: ["A", "B", "C"]

Orphan import

Typescript source:

import { keys } from 'ts-transformer-keys';
keys<{id:string}>();

Javascript output:

import { keys } from 'ts-transformer-keys';
["id"];

Node 12 behavior:

import { keys } from 'ts-transformer-keys';
         ^^^^
SyntaxError: The requested module 'ts-transformer-keys' does not provide an export named 'keys'

Compilation parameters

{
  "compilerOptions": {
    "module": "esnext",
  }
}

Transformer should remove import or his js should contains empty function:

export function keys(){
   throw new Error('See https://github.com/kimamula/ts-transformer-keys/blob/master/README.md#how-to-use-the-custom-transformer ');
}

deprecation warnings

DeprecationWarning: 'createLiteral' has been deprecated since v4.0.0. Use `factory.createStringLiteral`, `factory.createStringLiteralFromNode`, `factory.createNumericLiteral`, `factory.createBigIntLiteral`, `factory.createTrue`, `factory.createFalse`, or the factory supplied by your transformation context instead.
DeprecationWarning: 'createArrayLiteralExpression' has been deprecated since v4.0.0. Use the appropriate method on 'ts.factory' or the 'factory' supplied by your transformation context instead.

ts.createLiteral -> ts.factory.createStringLiteral
ts.createArrayLiteral -> ts.factory.createArrayLiteralExpression(

Uncaught (in promise) TypeError: keys is not a function at setup (index.vue:18:1) in Vue 3 app

Hi @kimamula,

First of all, thank you for this handy package. I'm trying to use this for my project where I need to extract the values from the API response and use only a few props to create the payload for update API. For this, I need something like this package. But unfortunately, it's giving the error Uncaught (in promise) TypeError: keys is not a function. I'm using the project setup with Vue 3, Typescript 4.7.4, Vite 3.0.4

My setup:

  • Vue - 3.2.37
  • Typescript - 4.7.4
  • ts-node - 10.9.1
  • ttypescript - 1.5.3
  • Vite - for tooling

This is my tsconfig.json:
image

And this is where I'm trying to use as given in the example to check:
image

As you can see there is no type error when I'm calling the keys function. But, still getting the error while checking in browser.

Error screenshot:
image

Any help would be greatly appreciated.

Thank you in advance.

Support for babel-loader?

Is there a way to get this working with babel-loader? Want to use it in a Create-React-App project which depends on babel-preset-react-app, which in turn depends on babel-typescript

Add support ttypescript transformer interface

I wrote a tool which patch ts on the fly and add support for custom transformers from tsconfig.json
https://github.com/cevek/ttypescript

{
    "compilerOptions": {
        "plugins": [
            {
                "customTransformers": {
                    "before": ["ts-transformer-keys"],
                }
            }
        ]
    }
}

but it works slightly different by calling your transformer directly and provide the program as second argument
This is transformer example:

import * as ts from 'typescript';
export default (ctx: ts.TransformationContext, program: ts.Program): ts.Transformer<ts.SourceFile> => {
    return sourceFile => {
        function visitor(node: ts.Node): ts.Node {
            return ts.visitEachChild(node, visitor, ctx);
        }
        return ts.visitEachChild(sourceFile, visitor, ctx);
    };
};

If you accept PR, I can add support for this

ERROR: ts_transformer_keys_1.keys is not a function

Not sure if it is my fault or not, but I'm using the README's example and getting this error:

const keysOfProps = keys<Props>();
                    ^
TypeError: ts_transformer_keys_1.keys is not a function
    at Object.<anonymous> (C:\Users\Gabriel\Projects\typescript-proj\index.ts:8:21)
    at Module._compile (module.js:649:30)
    at Module.m._compile (C:\Users\Gabriel\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:402:23)
    at Module._extensions..js (module.js:660:10)
    at Object.require.extensions.(anonymous function) [as .ts] (C:\Users\Gabriel\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:405:12)
    at Module.load (module.js:561:32)
    at tryModuleLoad (module.js:501:12)
    at Function.Module._load (module.js:493:3)
    at Function.Module.runMain (module.js:690:10)
    at Object.<anonymous> (C:\Users\Gabriel\AppData\Roaming\npm\node_modules\ts-node\src\bin.ts:145:12)

I have these dependencies:

  "dependencies": {
    "ts-transformer-keys": "^0.3.1",
    "typescript": "^2.8.3"
  }

My code:

import { keys } from 'ts-transformer-keys';

interface Props {
  id: string;
  name: string;
  age: number;
}
const keysOfProps = keys<Props>();

console.log(keysOfProps); // ['id', 'name', 'age']

Thanks in advance

Make this package work with generics

I know in your README you mentioned that this doesn't work with generic types, i.e.

keys<T>

This functionality would be incredibly useful to me if it worked - and I would love to help contribute if you have any ideas for how to get this to work.

Generics don't work

Hi,

I'm trying to make work the following code but I'm failing.

function func<T extends object>(): Array<keyof T> {
    return keys<T>();
}

console.log(keys<SomeInterface>()); // Logs SomeInterface keys.
console.log(func<SomeInterface>()); // Logs empty array.

Is there any solution?

Warning when using with AWS Lambda and Parcel

I have this message when using the library with a Lambda function written in Typescript (and transpile with Parcel)

asset-input/src/lambda-handlers/.../handler.ts:1:9: warning: Import "keys" will always be undefined 
because the file "asset-input/node_modules/ts-transformer-keys/index.js" has no exports
    1 │ import { keys } from 'ts-transformer-keys';
      ╵          ~~~~

1 warning

I think it is related to the fact that index.js in empty.

Any thought?

Usage with ts-jest

As far as I understood, ts-jest supports typescript transformers with the astTransformers option. I tried to make it work like this in my jest.config.js:

  globals: {
    'ts-jest': {
      astTransformers: {
        before: ['ts-transformer-keys/transformer'],
      },
    },
  },

This did not work and results in the error TypeError: ts_transformer_keys_1.keys is not a function, which happens when the transform is not being applied. Any ideas?

Why does keys() not work with dynamic inputs?

Hello,

I was just wondering why does the keys function not work with dynamic names passed to it?

Is this because of an inherent TypeScript limitation or is it a transformation function limitation?

For reference, this is what my code roughly looks like right now but does not seem to work
const instances = ['a','b','c'];
for(let instance of instances){
let instanceKeys = keys<NexusPrismaTypes[instance]>();
console.log(instanceKeys) //Returns an empty array
}

How to use with this with React + Typescript?

I pretty new to the typescript world, but figure out if I could extract the key from the interface it would be a perfect fit for what I need in react, but I can't find any tutorial to add it with React.

get this working with vue loader

I am pretty capable when it comes to wepack, so I expected to get this working. But , I am using vue 3 for the first time, and the webpack is .. different. You use a vue.config.js to set up a block to modify the webpack config with webpack-merge or webpack-chain. Since I want to mutate the ts loaders (I assumed), I used chain.. there's a few other configuration changes I have made, so my vue.config.ts looks like this:

const PackageVars = require('./package-vars.webpack-plugin.js')
const keysTransformer = require('ts-transformer-keys/transformer').default

module.exports = {
  configureWebpack: {
    plugins: [PackageVars]
  },

  chainWebpack: config => {
    const getCustomTransformers = program => ({
      before: [keysTransformer(program)]
    })

    ;['ts', 'tsx'].forEach(rule => {
      config.module
        .rule(rule)
        .use('ts-loader')
        .loader('ts-loader')
        .tap(options => Object.assign(options, { getCustomTransformers }))
    })
  },

  pluginOptions: {
    i18n: {
      locale: 'en',
      fallbackLocale: 'en',
      localeDir: 'locales',
      enableInSFC: true
    }
  },

  css: {
    loaderOptions: {
      sass: {
        prependData: `@import "@/styles/global.scss";`
      }
    }
  }
}

and that generates a webpack.config.js:

{
  mode: 'development',
  context: '/Users/me/Public/project',
  node: {
    setImmediate: false,
    process: 'mock',
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty'
  },
  output: {
    path: '/Users/me/Public/project/dist',
    filename: 'js/[name].js',
    publicPath: '/',
    chunkFilename: 'js/[name].js'
  },
  resolve: {
    alias: {
      '@': '/Users/me/Public/project/src',
      vue$: 'vue/dist/vue.runtime.esm.js'
    },
    extensions: [
      '.tsx',
      '.ts',
      '.mjs',
      '.js',
      '.jsx',
      '.vue',
      '.json',
      '.wasm'
    ],
    modules: [
      'node_modules',
      '/Users/me/Public/project/node_modules',
      '/Users/me/Public/project/node_modules/@vue/cli-service/node_modules'
    ]
  },
  resolveLoader: {
    modules: [
      '/Users/me/Public/project/node_modules/@vue/cli-plugin-typescript/node_modules',
      '/Users/me/Public/project/node_modules/@vue/cli-plugin-babel/node_modules',
      'node_modules',
      '/Users/me/Public/project/node_modules',
      '/Users/me/Public/project/node_modules/@vue/cli-service/node_modules'
    ]
  },
  module: {
    noParse: /^(vue|vue-router|vuex|vuex-router-sync)$/,
    rules: [
      /* config.module.rule('vue') */
      {
        test: /\.vue$/,
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/cache-loader/dist/cjs.js',
            options: {
              cacheDirectory: '/Users/me/Public/project/node_modules/.cache/vue-loader',
              cacheIdentifier: '1fc0539f'
            }
          },
          {
            loader: '/Users/me/Public/project/node_modules/vue-loader/lib/index.js',
            options: {
              compilerOptions: {
                whitespace: 'condense'
              },
              cacheDirectory: '/Users/me/Public/project/node_modules/.cache/vue-loader',
              cacheIdentifier: '1fc0539f'
            }
          }
        ]
      },
      /* config.module.rule('images') */
      {
        test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/url-loader/dist/cjs.js',
            options: {
              limit: 4096,
              fallback: {
                loader: 'file-loader',
                options: {
                  name: 'img/[name].[hash:8].[ext]'
                }
              }
            }
          }
        ]
      },
      /* config.module.rule('svg') */
      {
        test: /\.(svg)(\?.*)?$/,
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/file-loader/dist/cjs.js',
            options: {
              name: 'img/[name].[hash:8].[ext]'
            }
          }
        ]
      },
      /* config.module.rule('media') */
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/url-loader/dist/cjs.js',
            options: {
              limit: 4096,
              fallback: {
                loader: 'file-loader',
                options: {
                  name: 'media/[name].[hash:8].[ext]'
                }
              }
            }
          }
        ]
      },
      /* config.module.rule('fonts') */
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/url-loader/dist/cjs.js',
            options: {
              limit: 4096,
              fallback: {
                loader: 'file-loader',
                options: {
                  name: 'fonts/[name].[hash:8].[ext]'
                }
              }
            }
          }
        ]
      },
      /* config.module.rule('pug') */
      {
        test: /\.pug$/,
        oneOf: [
          /* config.module.rule('pug').oneOf('pug-vue') */
          {
            resourceQuery: /vue/,
            use: [
              {
                loader: 'pug-plain-loader'
              }
            ]
          },
          /* config.module.rule('pug').oneOf('pug-template') */
          {
            use: [
              {
                loader: 'raw-loader'
              },
              {
                loader: 'pug-plain-loader'
              }
            ]
          }
        ]
      },
      /* config.module.rule('css') */
      {
        test: /\.css$/,
        oneOf: [
          /* config.module.rule('css').oneOf('vue-modules') */
          {
            resourceQuery: /module/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2,
                  modules: {
                    localIdentName: '[name]_[local]_[hash:base64:5]'
                  }
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              }
            ]
          },
          /* config.module.rule('css').oneOf('vue') */
          {
            resourceQuery: /\?vue/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              }
            ]
          },
          /* config.module.rule('css').oneOf('normal-modules') */
          {
            test: /\.module\.\w+$/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2,
                  modules: {
                    localIdentName: '[name]_[local]_[hash:base64:5]'
                  }
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              }
            ]
          },
          /* config.module.rule('css').oneOf('normal') */
          {
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              }
            ]
          }
        ]
      },
      /* config.module.rule('postcss') */
      {
        test: /\.p(ost)?css$/,
        oneOf: [
          /* config.module.rule('postcss').oneOf('vue-modules') */
          {
            resourceQuery: /module/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2,
                  modules: {
                    localIdentName: '[name]_[local]_[hash:base64:5]'
                  }
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              }
            ]
          },
          /* config.module.rule('postcss').oneOf('vue') */
          {
            resourceQuery: /\?vue/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              }
            ]
          },
          /* config.module.rule('postcss').oneOf('normal-modules') */
          {
            test: /\.module\.\w+$/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2,
                  modules: {
                    localIdentName: '[name]_[local]_[hash:base64:5]'
                  }
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              }
            ]
          },
          /* config.module.rule('postcss').oneOf('normal') */
          {
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              }
            ]
          }
        ]
      },
      /* config.module.rule('scss') */
      {
        test: /\.scss$/,
        oneOf: [
          /* config.module.rule('scss').oneOf('vue-modules') */
          {
            resourceQuery: /module/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2,
                  modules: {
                    localIdentName: '[name]_[local]_[hash:base64:5]'
                  }
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/sass-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  implementation: {
                    run_: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    render: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    renderSync: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    info: 'dart-sass\t1.24.0\t(Sass Compiler)\t[Dart]\ndart2js\t2.7.0\t(Dart Compiler)\t[Dart]',
                    types: {
                      Boolean: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Color: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      List: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Map: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Null: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Number: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      String: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Error: function Error() { [native code] }
                    }
                  },
                  prependData: '@import "@/styles/global.scss";'
                }
              }
            ]
          },
          /* config.module.rule('scss').oneOf('vue') */
          {
            resourceQuery: /\?vue/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/sass-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  implementation: {
                    run_: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    render: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    renderSync: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    info: 'dart-sass\t1.24.0\t(Sass Compiler)\t[Dart]\ndart2js\t2.7.0\t(Dart Compiler)\t[Dart]',
                    types: {
                      Boolean: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Color: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      List: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Map: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Null: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Number: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      String: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Error: function Error() { [native code] }
                    }
                  },
                  prependData: '@import "@/styles/global.scss";'
                }
              }
            ]
          },
          /* config.module.rule('scss').oneOf('normal-modules') */
          {
            test: /\.module\.\w+$/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2,
                  modules: {
                    localIdentName: '[name]_[local]_[hash:base64:5]'
                  }
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/sass-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  implementation: {
                    run_: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    render: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    renderSync: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    info: 'dart-sass\t1.24.0\t(Sass Compiler)\t[Dart]\ndart2js\t2.7.0\t(Dart Compiler)\t[Dart]',
                    types: {
                      Boolean: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Color: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      List: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Map: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Null: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Number: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      String: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Error: function Error() { [native code] }
                    }
                  },
                  prependData: '@import "@/styles/global.scss";'
                }
              }
            ]
          },
          /* config.module.rule('scss').oneOf('normal') */
          {
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/sass-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  implementation: {
                    run_: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    render: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    renderSync: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    info: 'dart-sass\t1.24.0\t(Sass Compiler)\t[Dart]\ndart2js\t2.7.0\t(Dart Compiler)\t[Dart]',
                    types: {
                      Boolean: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Color: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      List: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Map: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Null: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Number: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      String: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Error: function Error() { [native code] }
                    }
                  },
                  prependData: '@import "@/styles/global.scss";'
                }
              }
            ]
          }
        ]
      },
      /* config.module.rule('sass') */
      {
        test: /\.sass$/,
        oneOf: [
          /* config.module.rule('sass').oneOf('vue-modules') */
          {
            resourceQuery: /module/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2,
                  modules: {
                    localIdentName: '[name]_[local]_[hash:base64:5]'
                  }
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/sass-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  implementation: {
                    run_: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    render: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    renderSync: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    info: 'dart-sass\t1.24.0\t(Sass Compiler)\t[Dart]\ndart2js\t2.7.0\t(Dart Compiler)\t[Dart]',
                    types: {
                      Boolean: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Color: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      List: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Map: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Null: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Number: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      String: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Error: function Error() { [native code] }
                    }
                  },
                  prependData: '@import "@/styles/global.scss";',
                  sassOptions: {
                    indentedSyntax: true
                  }
                }
              }
            ]
          },
          /* config.module.rule('sass').oneOf('vue') */
          {
            resourceQuery: /\?vue/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/sass-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  implementation: {
                    run_: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    render: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    renderSync: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    info: 'dart-sass\t1.24.0\t(Sass Compiler)\t[Dart]\ndart2js\t2.7.0\t(Dart Compiler)\t[Dart]',
                    types: {
                      Boolean: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Color: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      List: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Map: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Null: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Number: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      String: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Error: function Error() { [native code] }
                    }
                  },
                  prependData: '@import "@/styles/global.scss";',
                  sassOptions: {
                    indentedSyntax: true
                  }
                }
              }
            ]
          },
          /* config.module.rule('sass').oneOf('normal-modules') */
          {
            test: /\.module\.\w+$/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2,
                  modules: {
                    localIdentName: '[name]_[local]_[hash:base64:5]'
                  }
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/sass-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  implementation: {
                    run_: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    render: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    renderSync: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    info: 'dart-sass\t1.24.0\t(Sass Compiler)\t[Dart]\ndart2js\t2.7.0\t(Dart Compiler)\t[Dart]',
                    types: {
                      Boolean: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Color: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      List: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Map: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Null: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Number: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      String: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Error: function Error() { [native code] }
                    }
                  },
                  prependData: '@import "@/styles/global.scss";',
                  sassOptions: {
                    indentedSyntax: true
                  }
                }
              }
            ]
          },
          /* config.module.rule('sass').oneOf('normal') */
          {
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/sass-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  implementation: {
                    run_: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    render: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    renderSync: function () {
                      return _call(f, Array.prototype.slice.apply(arguments));
                    },
                    info: 'dart-sass\t1.24.0\t(Sass Compiler)\t[Dart]\ndart2js\t2.7.0\t(Dart Compiler)\t[Dart]',
                    types: {
                      Boolean: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Color: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      List: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Map: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Null: function () {
                        return _call(f, Array.prototype.slice.apply(arguments));
                      },
                      Number: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      String: function () {
                        return _call(f, this, Array.prototype.slice.apply(arguments));
                      },
                      Error: function Error() { [native code] }
                    }
                  },
                  prependData: '@import "@/styles/global.scss";',
                  sassOptions: {
                    indentedSyntax: true
                  }
                }
              }
            ]
          }
        ]
      },
      /* config.module.rule('less') */
      {
        test: /\.less$/,
        oneOf: [
          /* config.module.rule('less').oneOf('vue-modules') */
          {
            resourceQuery: /module/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2,
                  modules: {
                    localIdentName: '[name]_[local]_[hash:base64:5]'
                  }
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: 'less-loader',
                options: {
                  sourceMap: false
                }
              }
            ]
          },
          /* config.module.rule('less').oneOf('vue') */
          {
            resourceQuery: /\?vue/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: 'less-loader',
                options: {
                  sourceMap: false
                }
              }
            ]
          },
          /* config.module.rule('less').oneOf('normal-modules') */
          {
            test: /\.module\.\w+$/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2,
                  modules: {
                    localIdentName: '[name]_[local]_[hash:base64:5]'
                  }
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: 'less-loader',
                options: {
                  sourceMap: false
                }
              }
            ]
          },
          /* config.module.rule('less').oneOf('normal') */
          {
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: 'less-loader',
                options: {
                  sourceMap: false
                }
              }
            ]
          }
        ]
      },
      /* config.module.rule('stylus') */
      {
        test: /\.styl(us)?$/,
        oneOf: [
          /* config.module.rule('stylus').oneOf('vue-modules') */
          {
            resourceQuery: /module/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2,
                  modules: {
                    localIdentName: '[name]_[local]_[hash:base64:5]'
                  }
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: 'stylus-loader',
                options: {
                  sourceMap: false,
                  preferPathResolver: 'webpack'
                }
              }
            ]
          },
          /* config.module.rule('stylus').oneOf('vue') */
          {
            resourceQuery: /\?vue/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: 'stylus-loader',
                options: {
                  sourceMap: false,
                  preferPathResolver: 'webpack'
                }
              }
            ]
          },
          /* config.module.rule('stylus').oneOf('normal-modules') */
          {
            test: /\.module\.\w+$/,
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2,
                  modules: {
                    localIdentName: '[name]_[local]_[hash:base64:5]'
                  }
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: 'stylus-loader',
                options: {
                  sourceMap: false,
                  preferPathResolver: 'webpack'
                }
              }
            ]
          },
          /* config.module.rule('stylus').oneOf('normal') */
          {
            use: [
              {
                loader: '/Users/me/Public/project/node_modules/vue-style-loader/index.js',
                options: {
                  sourceMap: false,
                  shadowMode: false
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/css-loader/dist/cjs.js',
                options: {
                  sourceMap: false,
                  importLoaders: 2
                }
              },
              {
                loader: '/Users/me/Public/project/node_modules/postcss-loader/src/index.js',
                options: {
                  sourceMap: false,
                  plugins: [
                    function () { /* omitted long function */ }
                  ]
                }
              },
              {
                loader: 'stylus-loader',
                options: {
                  sourceMap: false,
                  preferPathResolver: 'webpack'
                }
              }
            ]
          }
        ]
      },
      /* config.module.rule('js') */
      {
        test: /\.m?jsx?$/,
        exclude: [
          function () { /* omitted long function */ }
        ],
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/cache-loader/dist/cjs.js',
            options: {
              cacheDirectory: '/Users/me/Public/project/node_modules/.cache/babel-loader',
              cacheIdentifier: '0fff5c38'
            }
          },
          {
            loader: '/Users/me/Public/project/node_modules/babel-loader/lib/index.js'
          }
        ]
      },
      /* config.module.rule('eslint') */
      {
        enforce: 'pre',
        test: /\.(vue|(j|t)sx?)$/,
        exclude: [
          /node_modules/,
          '/Users/me/Public/project/node_modules/@vue/cli-service/lib'
        ],
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/eslint-loader/index.js',
            options: {
              extensions: [
                '.js',
                '.jsx',
                '.vue',
                '.ts',
                '.tsx'
              ],
              cache: true,
              cacheIdentifier: '5749dfb1',
              emitWarning: false,
              emitError: false,
              eslintPath: '/Users/me/Public/project/node_modules/eslint',
              formatter: function () { /* omitted long function */ }
            }
          }
        ]
      },
      /* config.module.rule('ts') */
      {
        test: /\.ts$/,
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/cache-loader/dist/cjs.js',
            options: {
              cacheDirectory: '/Users/me/Public/project/node_modules/.cache/ts-loader',
              cacheIdentifier: 'b1785fd2'
            }
          },
          {
            loader: '/Users/me/Public/project/node_modules/babel-loader/lib/index.js'
          },
          {
            loader: 'ts-loader',
            options: {
              transpileOnly: true,
              appendTsSuffixTo: [
                '\\.vue$'
              ],
              happyPackMode: false,
              getCustomTransformers: program => ({
                before: [keysTransformer(program)]
              })
            }
          }
        ]
      },
      /* config.module.rule('tsx') */
      {
        test: /\.tsx$/,
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/cache-loader/dist/cjs.js',
            options: {
              cacheDirectory: '/Users/me/Public/project/node_modules/.cache/ts-loader',
              cacheIdentifier: 'b1785fd2'
            }
          },
          {
            loader: '/Users/me/Public/project/node_modules/babel-loader/lib/index.js'
          },
          {
            loader: 'ts-loader',
            options: {
              transpileOnly: true,
              happyPackMode: false,
              appendTsxSuffixTo: [
                '\\.vue$'
              ],
              getCustomTransformers: program => ({
                before: [keysTransformer(program)]
              })
            }
          }
        ]
      },
      /* config.module.rule('i18n') */
      {
        resourceQuery: /blockType=i18n/,
        type: 'javascript/auto',
        use: [
          {
            loader: '@kazupon/vue-i18n-loader'
          }
        ]
      }
    ]
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendors: {
          name: 'chunk-vendors',
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          chunks: 'initial'
        },
        common: {
          name: 'chunk-common',
          minChunks: 2,
          priority: -20,
          chunks: 'initial',
          reuseExistingChunk: true
        }
      }
    },
    minimizer: [
      {
        options: {
          test: /\.m?js(\?.*)?$/i,
          chunkFilter: () => true,
          warningsFilter: () => true,
          extractComments: false,
          sourceMap: true,
          cache: true,
          cacheKeys: defaultCacheKeys => defaultCacheKeys,
          parallel: true,
          include: undefined,
          exclude: undefined,
          minify: undefined,
          terserOptions: {
            compress: {
              arrows: false,
              collapse_vars: false,
              comparisons: false,
              computed_props: false,
              hoist_funs: false,
              hoist_props: false,
              hoist_vars: false,
              inline: false,
              loops: false,
              negate_iife: false,
              properties: false,
              reduce_funcs: false,
              reduce_vars: false,
              switches: false,
              toplevel: false,
              typeofs: false,
              booleans: true,
              if_return: true,
              sequences: true,
              unused: true,
              conditionals: true,
              dead_code: true,
              evaluate: true
            },
            mangle: {
              safari10: true
            }
          }
        }
      }
    ]
  },
  plugins: [
    /* config.plugin('vue-loader') */
    new VueLoaderPlugin(),
    /* config.plugin('define') */
    new DefinePlugin(
      {
        'process.env': {
          NODE_ENV: '"development"',
          VUE_APP_I18N_LOCALE: '"en"',
          VUE_APP_I18N_FALLBACK_LOCALE: '"en"',
          BASE_URL: '"/"'
        }
      }
    ),
    /* config.plugin('case-sensitive-paths') */
    new CaseSensitivePathsPlugin(),
    /* config.plugin('friendly-errors') */
    new FriendlyErrorsWebpackPlugin(
      {
        additionalTransformers: [
          function () { /* omitted long function */ }
        ],
        additionalFormatters: [
          function () { /* omitted long function */ }
        ]
      }
    ),
    /* config.plugin('html') */
    new HtmlWebpackPlugin(
      {
        templateParameters: function () { /* omitted long function */ },
        template: '/Users/me/Public/project/public/index.html'
      }
    ),
    /* config.plugin('pwa') */
    new HtmlPwaPlugin(
      {
        name: 'project'
      }
    ),
    /* config.plugin('preload') */
    new PreloadPlugin(
      {
        rel: 'preload',
        include: 'initial',
        fileBlacklist: [
          /\.map$/,
          /hot-update\.js$/
        ]
      }
    ),
    /* config.plugin('prefetch') */
    new PreloadPlugin(
      {
        rel: 'prefetch',
        include: 'asyncChunks'
      }
    ),
    /* config.plugin('copy') */
    new CopyPlugin(
      [
        {
          from: '/Users/me/Public/project/public',
          to: '/Users/me/Public/project/dist',
          toType: 'dir',
          ignore: [
            '.DS_Store',
            {
              glob: 'index.html',
              matchBase: false
            }
          ]
        }
      ]
    ),
    /* config.plugin('fork-ts-checker') */
    new ForkTsCheckerWebpackPlugin(
      {
        vue: true,
        tslint: false,
        formatter: 'codeframe',
        checkSyntacticErrors: false
      }
    ),
    {
      definitions: {
        'process.env': {
          PACKAGE_VERSION: '"2.0.0"',
          PACKAGE_NAME: '"project"'
        }
      }
    }
  ],
  entry: {
    app: [
      './src/main.ts'
    ]
  }
}

in my code I appended the demo from the readme to an interface I want to use (this is in a .ts file, not a .vue file, so I really half-expected this to work):

import { keys } from "ts-transformer-keys";

export interface FirebaseUser {
  uid: string;
  displayName?: string;
  email?: string;
  phoneNumber?: string;
  emailVerified: boolean;
  isAnonymous?: boolean;
}

const keysOfProps = keys<FirebaseUser>();

console.log({ keysOfProps });

this should simplify/reduce debt of factory methods like the following a lot:

export function factoryFirebaseUser(
  data = <Partial<FirebaseUser>>{}
): FirebaseUser {
  if (!data.hasOwnProperty("uid")) {
    data.uid = undefined;
  }
//...

  return data as FirebaseUser;
}

but when I run npm run serve I get: Uncaught ReferenceError: keys is not defined .. can you help me spot where else I need to add it?

how can this be used with ts-node (for node worker_threads ?)

a typical worker might look like:

worker.js

const path = require('path');
const { workerData } = require('worker_threads');

require('ts-node').register(workerData.registerOptions);
require('tsconfig-paths').register();
require(path.resolve(__dirname, workerData.path));

worker.ts

import { parentPort, workerData } from 'worker_threads'

import { getBlockAtDifficulty } from './utilities'

const { block, difficulty, index, step } = workerData

parentPort!.postMessage(getBlockAtDifficulty(block, difficulty, index, step))

and could be consumed with code like:

utilities.ts

/**
 * spawns threads to resolve hash at difficulty, publishing result in 
 * MultiService
 * @param block Block to resolve hash of
 * @param difficulty Difficulty of hash to resolve
 * @returns uuid of multiservice to subscribe to
 * usage:
 * const multiService = new MultiService()
 * const task = getBlockAtDifficultyMultiThreaded(myBlock, someDifficulty)
 * multiService.resolve$
 *   .pipe(first(resolution => resolution.hasOwnProperty(task)))
 *   .subscribe(resolution => onSuccess(resolution[task]))
 */
export function getBlockAtDifficultyMultiThreaded(block: Partial<Block>, difficulty: number): UUID {
  const uuid = Hash.uuid() // our task identifier
  const workers: Array<Worker> = []
  const threads = os.cpus()
  const registerOptions = getRegisterOptions()

  threads.forEach((_, index) => {
    const args = { block, difficulty, index, step: threads.length }
    const worker: Worker = new Worker('./worker.js', {
      workerData: {
        path: 'src/blockchain/get-block-at-difficulty.worker.ts',
        args,
        registerOptions
      }
    })

    workers.push(worker)
    worker.on('message', (result: Block) => {
      MultiService.resolve(new Promise(res => res(result)), uuid)
      workers.forEach(w => w.terminate())
    })
  })
  return uuid
}

function getRegisterOptions() {
  const registerOptions = require('../../tsconfig.json')
  registerOptions.files = true

  return registerOptions
}

this will expose hopefully enough of the tsconfig to compile most typescript. but it will produce the runtime error:

events.js:291
      throw er; // Unhandled 'error' event
      ^
TypeError [Error]: ts_transformer_keys_1.keys is not a function
    at isValidPartialBlock (/Users/robertotomas/Public/Github/learning-chain/src/blockchain/block/index.ts:109:22)
    at new Block (/Users/robertotomas/Public/Github/learning-chain/src/blockchain/block/index.ts:48:12)
    at Object.getBlockAtDifficulty (/Users/robertotomas/Public/Github/learning-chain/src/blockchain/utilities.ts:79:14)

see: https://github.com/robbiemu/learning-chain/tree/chain for details (and the utilities.spec.ts therein)

edit

closed because adding this line to the getRegisterOptions method above fixes the issue: registerOptions.compiler = 'ttypescript'

Make a sample of a working app

Please make a sample of a working app. Right now any usage results in the following error occur (Repo with a demo):

TypeError: ts_transformer_keys_1.keys is not a function
    at Object.<anonymous> (c:\Dev\ts-transformer-keys-issue-7\src\index.ts:26:21)
    at Module._compile (module.js:571:32)
    at Module.m._compile (c:\Dev\ts-transformer-keys-issue-7\node_modules\ts-node\src\index.ts:392:23)
    at Module._extensions..js (module.js:580:10)
    at Object.require.extensions.(anonymous function) [as .ts] (c:\Dev\ts-transformer-keys-issue-7\node_modules\ts-node\src\index.ts:395:12)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Function.Module.runMain (module.js:605:10)
    at Object.<anonymous> (c:\Dev\ts-transformer-keys-issue-7\node_modules\ts-node\src\_bin.ts:182:12)

or

TSError: ⨯ Unable to compile TypeScript
File 'c:/Dev/ts-transformer-keys-issue-7/node_modules/ts-transformer-keys/index.ts' is not under 'rootDir' 'C:/Dev/ts-transformer-keys-issue-7/src'. 'rootDir' is expected to contain all source files. (6059)
    at getOutput (c:\Dev\ts-transformer-keys-issue-7\node_modules\ts-node\src\index.ts:307:15)
    at c:\Dev\ts-transformer-keys-issue-7\node_modules\ts-node\src\index.ts:336:16
    at Object.compile (c:\Dev\ts-transformer-keys-issue-7\node_modules\ts-node\src\index.ts:498:11)
    at Module.m._compile (c:\Dev\ts-transformer-keys-issue-7\node_modules\ts-node\src\index.ts:392:43)
    at Module._extensions..js (module.js:580:10)
    at Object.require.extensions.(anonymous function) [as .ts] (c:\Dev\ts-transformer-keys-issue-7\node_modules\ts-node\src\index.ts:395:12)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Function.Module.runMain (module.js:605:10)

Can't import keysTransformer in a normal way

Not sure how to better express it than that, in the compiled JS file (transformer.js) in the NPM package, the transformer factory function is exported like this:

exports.default = transformer;

This means (for whatever weird and convoluted JS module export syntax reasons or whatever) that the module will now be imported as { default: [Function: transformer] }, meaning the code would have to look like this:

import keysTransformer from 'ts-transformer-keys/transform.js';

const theActualKeysTransformer = keysTransformer.default;

The export should go like this:

export default transformer

I suppose this is a TypeScript compilation target issue or something like that?

Perhaps the module option under compilationOptions in tsconfig.json should be set to es6?

Work with Union Types

Example:

import { keys } from "ts-transformer-keys"

type UserRegisterType = "Facebook" | "Twitter"
console.log("UserRegisterType List:", keys<UserRegisterType>())

This returns an error:

Type 'UserRegisterType' does not satisfy the constraint 'object'.
  Type '"Facebook"' is not assignable to type 'object'.

expected:

[ 'Facebook', 'Twitter' ]

Support for gulp

Hi,
Does this work with gulp? Is there any documentation on that?

Would it work with esbuild-loader?

Hello,

I'm curious if anyone managed to make it work with esbuild (esbuild-loader)?

Cheers.

(Sorry, probably not the right place to ask for this but I could not find ts-transformer-keys in GitHub Support Community...)

A way to get the data type

Is there a way to get the corresponding data type (string, number, etc.) of a key retrieived with keys<ISomeType>?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.