Repository: tailwindlabs/tailwindcss
File: packages/tailwindcss/src/index.ts (TypeScript)

Code before:
          throw new Error('`@plugin` can only contain declarations.')
        }

        if (decl.value === undefined) continue

        // Parse the declaration value as a primitive type
        // These are the same primitive values supported by JSON
        let value: CssPluginOptions[keyof CssPluginOptions] = decl.value

        if (value === 'null') {
          value = null
        } else if (value === 'true') {
          value = true
        } else if (value === 'false') {
          value = false
        } else if (!Number.isNaN(Number(value))) {
          value = Number(value)
        } else if (value[0] === '"' && value[value.length - 1] === '"') {
          value = value.slice(1, -1)
        } else if (value[0] === "'" && value[value.length - 1] === "'") {
          value = value.slice(1, -1)
        } else if (value[0] === '[' && value[value.length - 1] === ']') {
          throw new Error('Arrays are not supported in `@plugin` options.')
        } else if (value[0] === '{' && value[value.length - 1] === '}') {
          throw new Error('Objects are not supported in `@plugin` options.')
        }

        options[decl.property] = value
      }

      pluginPaths.push([
        node.selector.slice(9, -1),
        Object.keys(options).length > 0 ? options : null,
      ])

      replaceWith([])
      return
    }

    // Collect paths from `@config` at-rules
    if (node.selector === '@config' || node.selector.startsWith('@config ')) {
      if (node.nodes.length > 0) {
        throw new Error('`@config` cannot have a body.')
      }

      if (parent !== null) {
        throw new Error('`@config` cannot be nested.')
      }

      configPaths.push(node.selector.slice(9, -1))
      replaceWith([])

Review comment (suggestion):
Maybe those two errors could also say the property that this error was found and maybe give some options? (just brainstorming here though).

> Unexpected `@plugin` option. Value for declaration `foo: [...blabla]` is not supported. It looks like you want to pass an array to plugin options. This is not supported from CSS. Instead, create a custom JS plugin file: 
> 
> ``` 
> // ./my-plugin.js
> export default ...
> ```

(Ok the thing at the end should probably be a docs link)

Code after:

      let options: CssPluginOptions = {}

      for (let decl of node.nodes ?? []) {
        if (decl.kind !== 'declaration') {
          throw new Error(
            `Unexpected \`@plugin\` option:\n\n${toCss([decl])}\n\n\`@plugin\` options must be a flat list of declarations.`,
          )
        }

        if (decl.value === undefined) continue

        // Parse the declaration value as a primitive type
        // These are the same primitive values supported by JSON
        let value: CssPluginOptions[keyof CssPluginOptions] = decl.value

        let parts = segment(value, ',').map((part) => {
          part = part.trim()

          if (part === 'null') {
            return null
          } else if (part === 'true') {
            return true
          } else if (part === 'false') {
            return false
          } else if (!Number.isNaN(Number(part))) {
            return Number(part)
          } else if (
            (part[0] === '"' && part[part.length - 1] === '"') ||
            (part[0] === "'" && part[part.length - 1] === "'")
          ) {
            return part.slice(1, -1)
          } else if (part[0] === '{' && part[part.length - 1] === '}') {
            throw new Error(
              `Unexpected \`@plugin\` option: Value of declaration \`${toCss([decl]).trim()}\` is not supported.\n\nUsing an object as a plugin option is currently only supported in JavaScript configuration files.`,
            )
          }

          return part
        })

        options[decl.property] = parts.length === 1 ? parts[0] : parts
      }

      pluginPaths.push([pluginPath, Object.keys(options).length > 0 ? options : null])

      replaceWith([])
      return
    }

    // Collect paths from `@config` at-rules