@sanity/plugin-kit 0.0.1-studio-v3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +398 -0
- package/assets/splat/LICENSE +21 -0
- package/assets/splat/editorconfig +13 -0
- package/assets/splat/eslint.config.js +5 -0
- package/assets/splat/gitignore +55 -0
- package/assets/splat/npmignore +9 -0
- package/assets/splat/prettierrc.js +6 -0
- package/assets/splat/sanity.json +8 -0
- package/assets/splat/template-tsconfig.json +23 -0
- package/assets/splat/v2-incompatible.js.template +11 -0
- package/lib/package.json +127 -0
- package/lib/src/actions/init.d.ts +65 -0
- package/lib/src/actions/init.js +83 -0
- package/lib/src/actions/init.js.map +1 -0
- package/lib/src/actions/link-watch.d.ts +3 -0
- package/lib/src/actions/link-watch.js +69 -0
- package/lib/src/actions/link-watch.js.map +1 -0
- package/lib/src/actions/splat.d.ts +26 -0
- package/lib/src/actions/splat.js +296 -0
- package/lib/src/actions/splat.js.map +1 -0
- package/lib/src/actions/verify/types.d.ts +77 -0
- package/lib/src/actions/verify/types.js +3 -0
- package/lib/src/actions/verify/types.js.map +1 -0
- package/lib/src/actions/verify/validations.d.ts +28 -0
- package/lib/src/actions/verify/validations.js +379 -0
- package/lib/src/actions/verify/validations.js.map +1 -0
- package/lib/src/actions/verify/verify-common.d.ts +43 -0
- package/lib/src/actions/verify/verify-common.js +88 -0
- package/lib/src/actions/verify/verify-common.js.map +1 -0
- package/lib/src/actions/verify-package.d.ts +5 -0
- package/lib/src/actions/verify-package.js +72 -0
- package/lib/src/actions/verify-package.js.map +1 -0
- package/lib/src/actions/verify-studio.d.ts +5 -0
- package/lib/src/actions/verify-studio.js +55 -0
- package/lib/src/actions/verify-studio.js.map +1 -0
- package/lib/src/actions/verify.d.ts +0 -0
- package/lib/src/actions/verify.js +330 -0
- package/lib/src/actions/verify.js.map +1 -0
- package/lib/src/cli.d.ts +2 -0
- package/lib/src/cli.js +86 -0
- package/lib/src/cli.js.map +1 -0
- package/lib/src/cmds/index.d.ts +8 -0
- package/lib/src/cmds/index.js +12 -0
- package/lib/src/cmds/index.js.map +1 -0
- package/lib/src/cmds/init.d.ts +4 -0
- package/lib/src/cmds/init.js +90 -0
- package/lib/src/cmds/init.js.map +1 -0
- package/lib/src/cmds/link-watch.d.ts +4 -0
- package/lib/src/cmds/link-watch.js +49 -0
- package/lib/src/cmds/link-watch.js.map +1 -0
- package/lib/src/cmds/splat.d.ts +4 -0
- package/lib/src/cmds/splat.js +63 -0
- package/lib/src/cmds/splat.js.map +1 -0
- package/lib/src/cmds/verify-package.d.ts +4 -0
- package/lib/src/cmds/verify-package.js +38 -0
- package/lib/src/cmds/verify-package.js.map +1 -0
- package/lib/src/cmds/verify-studio.d.ts +4 -0
- package/lib/src/cmds/verify-studio.js +38 -0
- package/lib/src/cmds/verify-studio.js.map +1 -0
- package/lib/src/cmds/verify.d.ts +0 -0
- package/lib/src/cmds/verify.js +42 -0
- package/lib/src/cmds/verify.js.map +1 -0
- package/lib/src/cmds/version.d.ts +4 -0
- package/lib/src/cmds/version.js +55 -0
- package/lib/src/cmds/version.js.map +1 -0
- package/lib/src/configs/buildExtensions.d.ts +1 -0
- package/lib/src/configs/buildExtensions.js +5 -0
- package/lib/src/configs/buildExtensions.js.map +1 -0
- package/lib/src/configs/default-source.d.ts +3 -0
- package/lib/src/configs/default-source.js +70 -0
- package/lib/src/configs/default-source.js.map +1 -0
- package/lib/src/configs/merged-packages.d.ts +1 -0
- package/lib/src/configs/merged-packages.js +24 -0
- package/lib/src/configs/merged-packages.js.map +1 -0
- package/lib/src/configs/uselessFiles.d.ts +1 -0
- package/lib/src/configs/uselessFiles.js +33 -0
- package/lib/src/configs/uselessFiles.js.map +1 -0
- package/lib/src/constants.d.ts +11 -0
- package/lib/src/constants.js +15 -0
- package/lib/src/constants.js.map +1 -0
- package/lib/src/dependencies/find.d.ts +0 -0
- package/lib/src/dependencies/find.js +195 -0
- package/lib/src/dependencies/find.js.map +1 -0
- package/lib/src/dependencies/import-linter.d.ts +3 -0
- package/lib/src/dependencies/import-linter.js +112 -0
- package/lib/src/dependencies/import-linter.js.map +1 -0
- package/lib/src/index.d.ts +2 -0
- package/lib/src/index.js +6 -0
- package/lib/src/index.js.map +1 -0
- package/lib/src/npm/manager.d.ts +7 -0
- package/lib/src/npm/manager.js +62 -0
- package/lib/src/npm/manager.js.map +1 -0
- package/lib/src/npm/package.d.ts +8 -0
- package/lib/src/npm/package.js +288 -0
- package/lib/src/npm/package.js.map +1 -0
- package/lib/src/npm/publish.d.ts +1 -0
- package/lib/src/npm/publish.js +14 -0
- package/lib/src/npm/publish.js.map +1 -0
- package/lib/src/npm/resolveLatestVersions.d.ts +3 -0
- package/lib/src/npm/resolveLatestVersions.js +35 -0
- package/lib/src/npm/resolveLatestVersions.js.map +1 -0
- package/lib/src/sanity/manifest.d.ts +48 -0
- package/lib/src/sanity/manifest.js +263 -0
- package/lib/src/sanity/manifest.js.map +1 -0
- package/lib/src/sharedFlags.d.ts +15 -0
- package/lib/src/sharedFlags.js +17 -0
- package/lib/src/sharedFlags.js.map +1 -0
- package/lib/src/util/command-parser.d.ts +9 -0
- package/lib/src/util/command-parser.js +41 -0
- package/lib/src/util/command-parser.js.map +1 -0
- package/lib/src/util/errorToUndefined.d.ts +1 -0
- package/lib/src/util/errorToUndefined.js +11 -0
- package/lib/src/util/errorToUndefined.js.map +1 -0
- package/lib/src/util/files.d.ts +36 -0
- package/lib/src/util/files.js +253 -0
- package/lib/src/util/files.js.map +1 -0
- package/lib/src/util/log.d.ts +14 -0
- package/lib/src/util/log.js +36 -0
- package/lib/src/util/log.js.map +1 -0
- package/lib/src/util/prompt.d.ts +13 -0
- package/lib/src/util/prompt.js +75 -0
- package/lib/src/util/prompt.js.map +1 -0
- package/lib/src/util/readme.d.ts +5 -0
- package/lib/src/util/readme.js +73 -0
- package/lib/src/util/readme.js.map +1 -0
- package/lib/src/util/request.d.ts +1 -0
- package/lib/src/util/request.js +19 -0
- package/lib/src/util/request.js.map +1 -0
- package/lib/src/util/user.d.ts +10 -0
- package/lib/src/util/user.js +106 -0
- package/lib/src/util/user.js.map +1 -0
- package/lib/test/cli.test.d.ts +1 -0
- package/lib/test/cli.test.js +64 -0
- package/lib/test/cli.test.js.map +1 -0
- package/lib/test/fixture-utils.d.ts +25 -0
- package/lib/test/fixture-utils.js +67 -0
- package/lib/test/fixture-utils.js.map +1 -0
- package/lib/test/init-verify-build.test.d.ts +1 -0
- package/lib/test/init-verify-build.test.js +75 -0
- package/lib/test/init-verify-build.test.js.map +1 -0
- package/lib/test/init.test.d.ts +1 -0
- package/lib/test/init.test.js +137 -0
- package/lib/test/init.test.js.map +1 -0
- package/lib/test/run-test-command.d.ts +1 -0
- package/lib/test/run-test-command.js +6 -0
- package/lib/test/run-test-command.js.map +1 -0
- package/lib/test/verify-package.test.d.ts +1 -0
- package/lib/test/verify-package.test.js +81 -0
- package/lib/test/verify-package.test.js.map +1 -0
- package/lib/test/version.test.d.ts +1 -0
- package/lib/test/version.test.js +48 -0
- package/lib/test/version.test.js.map +1 -0
- package/package.json +127 -0
- package/src/actions/init.ts +104 -0
- package/src/actions/link-watch.ts +74 -0
- package/src/actions/splat.ts +366 -0
- package/src/actions/verify/types.ts +84 -0
- package/src/actions/verify/validations.ts +401 -0
- package/src/actions/verify/verify-common.ts +92 -0
- package/src/actions/verify-package.ts +87 -0
- package/src/actions/verify-studio.ts +55 -0
- package/src/actions/verify.ts +328 -0
- package/src/cli.ts +77 -0
- package/src/cmds/index.ts +9 -0
- package/src/cmds/init.ts +85 -0
- package/src/cmds/link-watch.ts +51 -0
- package/src/cmds/splat.ts +59 -0
- package/src/cmds/verify-package.ts +36 -0
- package/src/cmds/verify-studio.ts +36 -0
- package/src/cmds/verify.ts +40 -0
- package/src/cmds/version.ts +67 -0
- package/src/configs/buildExtensions.ts +1 -0
- package/src/configs/default-source.ts +68 -0
- package/src/configs/merged-packages.ts +20 -0
- package/src/configs/uselessFiles.ts +29 -0
- package/src/constants.ts +13 -0
- package/src/dependencies/find.ts +193 -0
- package/src/dependencies/import-linter.ts +103 -0
- package/src/index.ts +4 -0
- package/src/npm/manager.ts +44 -0
- package/src/npm/package.ts +370 -0
- package/src/npm/publish.ts +9 -0
- package/src/npm/resolveLatestVersions.ts +26 -0
- package/src/sanity/manifest.ts +340 -0
- package/src/sharedFlags.ts +14 -0
- package/src/util/command-parser.ts +31 -0
- package/src/util/errorToUndefined.ts +7 -0
- package/src/util/files.ts +249 -0
- package/src/util/log.ts +44 -0
- package/src/util/prompt.ts +70 -0
- package/src/util/readme.ts +72 -0
- package/src/util/request.ts +13 -0
- package/src/util/user.ts +110 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import meow from 'meow'
|
|
3
|
+
import {verifyPackage} from '../actions/verify-package'
|
|
4
|
+
import {cliName} from '../constants'
|
|
5
|
+
import {verifyFlags} from '../actions/verify/verify-common'
|
|
6
|
+
|
|
7
|
+
const description = `Verify that a Sanity plugin package is v3 compatible, and print upgrade steps if not.`
|
|
8
|
+
|
|
9
|
+
const help = `
|
|
10
|
+
Usage
|
|
11
|
+
$ ${cliName} verify-package [dir] [<args>]
|
|
12
|
+
|
|
13
|
+
Options
|
|
14
|
+
--single Enables fail-fast mode: Will only output the first validation that fails.
|
|
15
|
+
--silent Do not print info and warning messages
|
|
16
|
+
--verbose Log everything. This option conflicts with --silent
|
|
17
|
+
--version Output the version number
|
|
18
|
+
--help Output usage information
|
|
19
|
+
|
|
20
|
+
Each check will describe how they can be individually disabled.
|
|
21
|
+
|
|
22
|
+
Examples
|
|
23
|
+
# Verify Sanity plugin package in current directory
|
|
24
|
+
$ ${cliName} verify-package
|
|
25
|
+
|
|
26
|
+
# Verify Sanity plugin package in my-plugin directory in silent mode
|
|
27
|
+
$ ${cliName} verify-package my-plugin-directory --silent
|
|
28
|
+
`
|
|
29
|
+
|
|
30
|
+
function run({argv}: {argv: string[]}) {
|
|
31
|
+
const cli = meow(help, {flags: verifyFlags, argv, description})
|
|
32
|
+
const basePath = path.resolve(cli.input[0] || process.cwd())
|
|
33
|
+
return verifyPackage({basePath, flags: cli.flags})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default run
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import meow from 'meow'
|
|
3
|
+
import {cliName} from '../constants'
|
|
4
|
+
import {verifyFlags} from '../actions/verify/verify-common'
|
|
5
|
+
import {verifyStudio} from '../actions/verify-studio'
|
|
6
|
+
|
|
7
|
+
const description = `Verify that a Sanity Studio is configured correctly for v3, and print upgrade steps if not.`
|
|
8
|
+
|
|
9
|
+
const help = `
|
|
10
|
+
Usage
|
|
11
|
+
$ ${cliName} verify-studio [dir] [<args>]
|
|
12
|
+
|
|
13
|
+
Options
|
|
14
|
+
--single Enables fail-fast mode: Will only output the first validation that fails.
|
|
15
|
+
--silent Do not print info and warning messages
|
|
16
|
+
--verbose Log everything. This option conflicts with --silent
|
|
17
|
+
--version Output the version number
|
|
18
|
+
--help Output usage information
|
|
19
|
+
|
|
20
|
+
Each check will describe how they can be individually disabled.
|
|
21
|
+
|
|
22
|
+
Examples
|
|
23
|
+
# Verify Sanity Studio in current directory
|
|
24
|
+
$ ${cliName} verify-studio
|
|
25
|
+
|
|
26
|
+
# Verify Sanity Studio in my-sanity-studio directory in silent mode
|
|
27
|
+
$ ${cliName} verify-studio my-sanity-studio --silent
|
|
28
|
+
`
|
|
29
|
+
|
|
30
|
+
function run({argv}: {argv: string[]}) {
|
|
31
|
+
const cli = meow(help, {flags: verifyFlags, argv, description})
|
|
32
|
+
const basePath = path.resolve(cli.input[0] || process.cwd())
|
|
33
|
+
return verifyStudio({basePath, flags: cli.flags})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default run
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import meow from 'meow'
|
|
4
|
+
import pkg from '../../package.json'
|
|
5
|
+
import {verify} from '../actions/verify'
|
|
6
|
+
import sharedFlags from '../sharedFlags'
|
|
7
|
+
|
|
8
|
+
const description = `Verify that a Sanity plugin is ready for publishing`
|
|
9
|
+
|
|
10
|
+
const help = `
|
|
11
|
+
Usage
|
|
12
|
+
$ ${pkg.binname} verify [<dir>]
|
|
13
|
+
|
|
14
|
+
Examples
|
|
15
|
+
# Verify the plugin in the current directory
|
|
16
|
+
$ ${pkg.binname} verify
|
|
17
|
+
|
|
18
|
+
# Verify the plugin in ~/my-plugin
|
|
19
|
+
$ ${pkg.binname} verify ~/my-plugin
|
|
20
|
+
|
|
21
|
+
# Allow package.json to reference files inside the uncompiled source folder
|
|
22
|
+
$ ${pkg.binname} verify --allow-source-target
|
|
23
|
+
`
|
|
24
|
+
|
|
25
|
+
const flags = {
|
|
26
|
+
...sharedFlags,
|
|
27
|
+
allowSourceTarget: {
|
|
28
|
+
type: 'boolean',
|
|
29
|
+
default: false,
|
|
30
|
+
},
|
|
31
|
+
} as const
|
|
32
|
+
|
|
33
|
+
function run({argv}: {argv: string[]}) {
|
|
34
|
+
const cli = meow(help, {flags, argv, description})
|
|
35
|
+
const basePath = path.resolve(cli.input[0] || process.cwd())
|
|
36
|
+
return verify({basePath, flags: cli.flags})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default run
|
|
40
|
+
*/
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import meow from 'meow'
|
|
2
|
+
import pkg from '../../package.json'
|
|
3
|
+
import log from '../util/log'
|
|
4
|
+
import sharedFlags from '../sharedFlags'
|
|
5
|
+
|
|
6
|
+
const description = `Show the installed version of ${pkg.name}`
|
|
7
|
+
|
|
8
|
+
const help = `
|
|
9
|
+
Usage
|
|
10
|
+
$ ${pkg.binname} version
|
|
11
|
+
|
|
12
|
+
Options
|
|
13
|
+
--major Show only the major version
|
|
14
|
+
--minor Show only the minor version
|
|
15
|
+
--patch Show only the patch version
|
|
16
|
+
|
|
17
|
+
Examples
|
|
18
|
+
$ ${pkg.binname} version
|
|
19
|
+
${pkg.name} version ${pkg.version}
|
|
20
|
+
|
|
21
|
+
$ ${pkg.binname} version --major
|
|
22
|
+
${pkg.version.split('.')[0]}
|
|
23
|
+
`
|
|
24
|
+
|
|
25
|
+
const flags = {
|
|
26
|
+
...sharedFlags,
|
|
27
|
+
|
|
28
|
+
major: {
|
|
29
|
+
type: 'boolean',
|
|
30
|
+
default: false,
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
minor: {
|
|
34
|
+
type: 'boolean',
|
|
35
|
+
default: false,
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
patch: {
|
|
39
|
+
type: 'boolean',
|
|
40
|
+
default: false,
|
|
41
|
+
},
|
|
42
|
+
} as const
|
|
43
|
+
|
|
44
|
+
function run({argv}: {argv: string[]}) {
|
|
45
|
+
const cli = meow(help, {flags, argv, description})
|
|
46
|
+
const versionParts = pkg.version.split('.')
|
|
47
|
+
const versionNames = ['major', 'minor', 'patch']
|
|
48
|
+
const versionFlags = versionNames.filter((flagName) => cli.flags[flagName])
|
|
49
|
+
const versionFlag = versionFlags[0]
|
|
50
|
+
const numVersionFlags = versionFlags.length
|
|
51
|
+
|
|
52
|
+
if (numVersionFlags === 0) {
|
|
53
|
+
log.msg(`${pkg.name} version ${pkg.version}`)
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (numVersionFlags > 1) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`--major, --minor and --patch are mutually exclusive - only one can be used at a time`
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const partIndex = versionNames.indexOf(versionFlag)
|
|
64
|
+
log.msg(versionParts[partIndex])
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default run
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const buildExtensions = ['.js', '.jsx', '.es6', '.es', '.mjs', '.ts', '.tsx']
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import outdent from 'outdent'
|
|
2
|
+
import {PackageJson} from '../actions/verify/types'
|
|
3
|
+
|
|
4
|
+
export function defaultSourceJs(pkg: PackageJson) {
|
|
5
|
+
return (
|
|
6
|
+
outdent`
|
|
7
|
+
import {createPlugin} from 'sanity'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* ## Usage in sanity.config.js (or .js)
|
|
11
|
+
*
|
|
12
|
+
* \`\`\`
|
|
13
|
+
* import {createConfig} from 'sanity'
|
|
14
|
+
* import {myPlugin} from '${pkg.name}'
|
|
15
|
+
*
|
|
16
|
+
* export const createConfig({
|
|
17
|
+
* /...
|
|
18
|
+
* plugins: [
|
|
19
|
+
* myPlugin({})
|
|
20
|
+
* ]
|
|
21
|
+
* })
|
|
22
|
+
* \`\`\`
|
|
23
|
+
*/
|
|
24
|
+
export const myPlugin = createPlugin((config = {}) => {
|
|
25
|
+
// eslint-disable-next-line no-console
|
|
26
|
+
console.log(\`hello from ${pkg.name}\`)
|
|
27
|
+
return {
|
|
28
|
+
name: '${pkg.name}',
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
`.trimStart() + '\n'
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function defaultSourceTs(pkg: PackageJson) {
|
|
36
|
+
return (
|
|
37
|
+
outdent`
|
|
38
|
+
import {createPlugin} from 'sanity'
|
|
39
|
+
|
|
40
|
+
interface MyPluginConfig {
|
|
41
|
+
/* nothing here yet */
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* ## Usage in sanity.config.ts (or .js)
|
|
46
|
+
*
|
|
47
|
+
* \`\`\`
|
|
48
|
+
* import {createConfig} from 'sanity'
|
|
49
|
+
* import {myPlugin} from '${pkg.name}'
|
|
50
|
+
*
|
|
51
|
+
* export const createConfig({
|
|
52
|
+
* /...
|
|
53
|
+
* plugins: [
|
|
54
|
+
* myPlugin()
|
|
55
|
+
* ]
|
|
56
|
+
* })
|
|
57
|
+
* \`\`\`
|
|
58
|
+
*/
|
|
59
|
+
export const myPlugin = createPlugin<MyPluginConfig | void>((config = {}) => {
|
|
60
|
+
// eslint-disable-next-line no-console
|
|
61
|
+
console.log('hello from ${pkg.name}')
|
|
62
|
+
return {
|
|
63
|
+
name: '${pkg.name}',
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
`.trimStart() + '\n'
|
|
67
|
+
)
|
|
68
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const mergedPackages = [
|
|
2
|
+
'@sanity/base',
|
|
3
|
+
'@sanity/core',
|
|
4
|
+
'@sanity/cli',
|
|
5
|
+
'@sanity/types',
|
|
6
|
+
'@sanity/data-aspects',
|
|
7
|
+
'@sanity/default-layout',
|
|
8
|
+
'@sanity/default-login',
|
|
9
|
+
'@sanity/desk-tool',
|
|
10
|
+
'@sanity/field',
|
|
11
|
+
'@sanity/form-builder',
|
|
12
|
+
'@sanity/initial-value-templates',
|
|
13
|
+
'@sanity/language-filter',
|
|
14
|
+
'@sanity/production-preview',
|
|
15
|
+
'@sanity/react-hooks',
|
|
16
|
+
'@sanity/resolver',
|
|
17
|
+
'@sanity/state-router',
|
|
18
|
+
'@sanity/structure',
|
|
19
|
+
'@sanity/studio-hints',
|
|
20
|
+
].sort()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const uselessFiles = [
|
|
2
|
+
'.babel.config.js',
|
|
3
|
+
'.babelrc',
|
|
4
|
+
'.drone.yml',
|
|
5
|
+
'.editorconfig',
|
|
6
|
+
'.eslintignore',
|
|
7
|
+
'.eslintrc-ts.js',
|
|
8
|
+
'.eslintrc-ts',
|
|
9
|
+
'.eslintrc',
|
|
10
|
+
'.gitignore',
|
|
11
|
+
'.github',
|
|
12
|
+
'.nyc_output',
|
|
13
|
+
'.prettierrc',
|
|
14
|
+
'.stylelintignore',
|
|
15
|
+
'.stylelintrc.json',
|
|
16
|
+
'.stylelintrc',
|
|
17
|
+
'.travis.yaml',
|
|
18
|
+
'.travis.yml',
|
|
19
|
+
'babel.config.js',
|
|
20
|
+
'coverage',
|
|
21
|
+
'gulpfile.js',
|
|
22
|
+
'lcov-report',
|
|
23
|
+
'lerna.json',
|
|
24
|
+
'now.json',
|
|
25
|
+
'vercel.json',
|
|
26
|
+
'netlify.toml',
|
|
27
|
+
'postcss.config.js',
|
|
28
|
+
'tsconfig.json',
|
|
29
|
+
]
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const cliName = '@sanity/plugin-kit'
|
|
2
|
+
|
|
3
|
+
export const urls = {
|
|
4
|
+
refDocs: 'https://beta.sanity.io/docs/reference',
|
|
5
|
+
migrationGuideStudio: 'https://beta.sanity.io/docs/platform/v2-to-v3',
|
|
6
|
+
migrationGuidePlugin: 'https://beta.sanity.io/docs/platform/v2-to-v3/plugins',
|
|
7
|
+
pluginReadme: 'https://github.com/sanity-io/plugin-kit',
|
|
8
|
+
incompatiblePlugin: 'https://github.com/sanity-io/incompatible-plugin',
|
|
9
|
+
sanityExchange: 'https://www.sanity.io/exchange',
|
|
10
|
+
linterPackage: 'https://github.com/sanity-io/eslint-config-no-v2-imports',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const incompatiblePluginPackage = '@sanity/incompatible-plugin'
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/*
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import postcss from 'postcss'
|
|
5
|
+
import {discoverPathSync} from 'discover-path'
|
|
6
|
+
import traverse from '@babel/traverse'
|
|
7
|
+
import {parseSync} from '@babel/core'
|
|
8
|
+
|
|
9
|
+
export default {findDependencies}
|
|
10
|
+
|
|
11
|
+
const partReg = /^(all:part|part|config|sanity):/
|
|
12
|
+
const importReg = /^(?:"([^"]+)"|'([^']+)')$/
|
|
13
|
+
const composesReg = /^(.+?)\s+from\s+(?:"([^"]+)"|'([^']+)'|(global))$/
|
|
14
|
+
|
|
15
|
+
function findDependenciesFromFiles(files, seen = new Set<string>()): string[] {
|
|
16
|
+
const dependencies = new Set<string>()
|
|
17
|
+
files.forEach((file) => findDependencies(file, seen).forEach((dep) => dependencies.add(dep)))
|
|
18
|
+
return Array.from(dependencies)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function findDependenciesInCss(css, entryPath, processDependency) {
|
|
22
|
+
let ast
|
|
23
|
+
try {
|
|
24
|
+
ast = postcss.parse(css)
|
|
25
|
+
} catch (err: any) {
|
|
26
|
+
throw new Error(`Error parsing file (${entryPath}): ${err.message}`)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
ast.walkDecls(/^composes/, (decl) => {
|
|
30
|
+
const matches = decl.value.match(composesReg)
|
|
31
|
+
if (!matches) {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const [, , doubleQuotePath, singleQuotePath] = matches
|
|
36
|
+
const importPath = doubleQuotePath || singleQuotePath
|
|
37
|
+
if (importPath) {
|
|
38
|
+
processDependency(importPath)
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
ast.walkAtRules('import', (rule) => {
|
|
43
|
+
const matches = rule.params.match(importReg)
|
|
44
|
+
if (!matches) {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const [, doubleQuotePath, singleQuotePath] = matches
|
|
49
|
+
const importPath = doubleQuotePath || singleQuotePath
|
|
50
|
+
if (importPath) {
|
|
51
|
+
processDependency(importPath)
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface Traverse {
|
|
57
|
+
node: {callee: {name: string}; source: {value: string}; arguments: {value: string}[]}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function findDependenciesInJs(
|
|
61
|
+
js: string,
|
|
62
|
+
entryPath: string,
|
|
63
|
+
processDependency: (val: string) => void
|
|
64
|
+
) {
|
|
65
|
+
let ast
|
|
66
|
+
try {
|
|
67
|
+
ast = parseSync(js, {babelrc: false})
|
|
68
|
+
} catch (err: any) {
|
|
69
|
+
throw new Error(`Error parsing file (${entryPath}): ${err.message}`)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
traverse(ast, {
|
|
73
|
+
ImportDeclaration({node}: Traverse) {
|
|
74
|
+
processDependency(node.source.value)
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
CallExpression({node}: Traverse) {
|
|
78
|
+
if (node.callee.name === 'require') {
|
|
79
|
+
processDependency(node.arguments[0].value)
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function findDependencies(entryPath: string, seen = new Set<string>()): string[] {
|
|
86
|
+
if (Array.isArray(entryPath)) {
|
|
87
|
+
return findDependenciesFromFiles(entryPath, seen)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
seen.add(entryPath)
|
|
91
|
+
|
|
92
|
+
let content
|
|
93
|
+
try {
|
|
94
|
+
content = fs.readFileSync(entryPath, 'utf8')
|
|
95
|
+
} catch (err: any) {
|
|
96
|
+
throw new Error(`Error reading file (${entryPath}): ${err.message}`)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const dir = path.dirname(entryPath)
|
|
100
|
+
const dependencies = new Set<string>()
|
|
101
|
+
|
|
102
|
+
if (entryPath.endsWith('.css')) {
|
|
103
|
+
findDependenciesInCss(content, entryPath, processDependency)
|
|
104
|
+
} else {
|
|
105
|
+
findDependenciesInJs(content, entryPath, processDependency)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function processDependency(requirePath: string) {
|
|
109
|
+
if (typeof requirePath !== 'string') {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Don't allow absolute requires
|
|
114
|
+
if (path.isAbsolute(requirePath)) {
|
|
115
|
+
throw new Error(
|
|
116
|
+
`Absolute paths cannot be used in require/import statements: ${entryPath} references path "${requirePath}"`
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const isRelative = requirePath.startsWith('.')
|
|
121
|
+
const depPath = isRelative && resolveDependency(dir, requirePath, entryPath)
|
|
122
|
+
|
|
123
|
+
if (
|
|
124
|
+
depPath &&
|
|
125
|
+
['.js', '.css', '.esm', '.mjs', '.jsx'].includes(path.extname(depPath)) &&
|
|
126
|
+
!seen.has(depPath)
|
|
127
|
+
) {
|
|
128
|
+
// For relative javascript/css requires, recurse to find all depdendencies
|
|
129
|
+
findDependencies(depPath, seen).forEach((dep) => dependencies.add(dep))
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (isRelative) {
|
|
134
|
+
// Not JS? Skip it
|
|
135
|
+
return
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// For parts, we want the entire path, as we might want to validate them
|
|
139
|
+
if (partReg.test(requirePath)) {
|
|
140
|
+
dependencies.add(requirePath)
|
|
141
|
+
return
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// For modules, resolve the base module name, then add them
|
|
145
|
+
// eg: `codemirror/mode/javascript` => `codemirror`
|
|
146
|
+
// eg: `@sanity/base/foo/bar.js` => `@sanity/base`
|
|
147
|
+
const dep = requirePath.startsWith('@')
|
|
148
|
+
? requirePath.replace(/^(@[^/]+\/[^/]+)(\/.*|$)/, '$1')
|
|
149
|
+
: requirePath.replace(/^([^/]+)(\/.*|$)/, '$1')
|
|
150
|
+
|
|
151
|
+
dependencies.add(dep)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return Array.from(dependencies)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function resolveDependency(fromDir: string, toPath: string, entryPath: string) {
|
|
158
|
+
const [querylessPath] = toPath.split('?', 1)
|
|
159
|
+
|
|
160
|
+
let depPath
|
|
161
|
+
try {
|
|
162
|
+
depPath = require.resolve(path.resolve(fromDir, querylessPath))
|
|
163
|
+
} catch (err) {
|
|
164
|
+
throw new Error(`Unable to resolve "${querylessPath}" from ${entryPath}`)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
let actualPath
|
|
168
|
+
try {
|
|
169
|
+
actualPath = discoverPathSync(depPath)
|
|
170
|
+
} catch (err: any) {
|
|
171
|
+
const paths = (err.suggestions || []).map((suggested: string) =>
|
|
172
|
+
getDidYouMeanPath(querylessPath, suggested)
|
|
173
|
+
)
|
|
174
|
+
const didYouMean = paths ? `Did you mean:\n${paths.join('\n- ')}` : ''
|
|
175
|
+
throw new Error(`Unable to resolve "${querylessPath}" from ${entryPath}. ${didYouMean}`)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (actualPath !== depPath) {
|
|
179
|
+
const didYouMean = getDidYouMeanPath(querylessPath, actualPath)
|
|
180
|
+
throw new Error(
|
|
181
|
+
`Unable to resolve "${querylessPath} from ${entryPath}. Did you mean "${didYouMean}"?`
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return actualPath
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function getDidYouMeanPath(wanted: string, suggested: string) {
|
|
189
|
+
const end = wanted.replace(/[./]+/, '')
|
|
190
|
+
const start = wanted.slice(0, 0 - end.length)
|
|
191
|
+
return `${start}${suggested.slice(0 - end.length)}`
|
|
192
|
+
}
|
|
193
|
+
*/
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import log from '../util/log'
|
|
2
|
+
import {mergedPackages} from '../configs/merged-packages'
|
|
3
|
+
import {urls} from '../constants'
|
|
4
|
+
import {ESLint} from 'eslint'
|
|
5
|
+
import path from 'path'
|
|
6
|
+
import outdent from 'outdent'
|
|
7
|
+
|
|
8
|
+
const removedImportSuffix = `imports where removed in Sanity v3. Please refer to the migration guide: ${urls.migrationGuideStudio}, or new API-reference docs: ${urls.refDocs}`
|
|
9
|
+
|
|
10
|
+
export async function validateImports({basePath}: {basePath: string}): Promise<string[]> {
|
|
11
|
+
log.debug('Running ESLint with Sanity Studio import hints...')
|
|
12
|
+
const eslint = new ESLint({
|
|
13
|
+
cwd: basePath,
|
|
14
|
+
overrideConfig: {
|
|
15
|
+
ignorePatterns: ['node_modules'],
|
|
16
|
+
rules: {
|
|
17
|
+
'no-restricted-imports': [
|
|
18
|
+
'error',
|
|
19
|
+
{
|
|
20
|
+
patterns: [
|
|
21
|
+
...mergedPackages.map((packageName) => ({
|
|
22
|
+
group: [`${packageName}*`],
|
|
23
|
+
message: `Use sanity instead of ${packageName}.`,
|
|
24
|
+
})),
|
|
25
|
+
{
|
|
26
|
+
group: ['config:*'],
|
|
27
|
+
message: `config: imports are no longer supported. Please see the new plugin API for alternatives: ${urls.migrationGuideStudio}`,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
group: ['part:*'],
|
|
31
|
+
message: `part: ${removedImportSuffix}`,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
group: ['all:part:*'],
|
|
35
|
+
message: `all:part: ${removedImportSuffix}`,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
group: ['sanity:*'],
|
|
39
|
+
message: `sanity: ${removedImportSuffix}`,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const results = await eslint.lintFiles([path.join(basePath, '**/*.{js,jsx,ts,tsx}')])
|
|
50
|
+
|
|
51
|
+
const onlyImportErrors = results
|
|
52
|
+
.map((r) => {
|
|
53
|
+
const limitErrors = r.messages.filter((m) => m.ruleId === 'no-restricted-imports')
|
|
54
|
+
return {
|
|
55
|
+
...r,
|
|
56
|
+
messages: limitErrors,
|
|
57
|
+
errorCount: limitErrors.length,
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
.filter((r) => r.errorCount)
|
|
61
|
+
|
|
62
|
+
if (onlyImportErrors.length) {
|
|
63
|
+
const formatter = await eslint.loadFormatter('stylish')
|
|
64
|
+
const resultText = await formatter.format(onlyImportErrors)
|
|
65
|
+
|
|
66
|
+
const addtionalInfo = outdent`
|
|
67
|
+
ESLint detected Studio V2 imports that are no longer available.
|
|
68
|
+
It is recommended configure @sanity/eslint-config-no-v2-imports for ESLint.
|
|
69
|
+
|
|
70
|
+
Run:
|
|
71
|
+
npm install --save-dev @sanity/eslint-config-no-v2-imports
|
|
72
|
+
|
|
73
|
+
In .eslintrc add:
|
|
74
|
+
"extends": ["@sanity/no-v2-imports"]
|
|
75
|
+
|
|
76
|
+
This way, V2-imports can be identified directly in the IDE, or using eslint CLI.
|
|
77
|
+
For more, see ${urls.linterPackage}
|
|
78
|
+
|
|
79
|
+
If the plugin package does not use eslint, disable this check.
|
|
80
|
+
`
|
|
81
|
+
return [resultText + addtionalInfo]
|
|
82
|
+
}
|
|
83
|
+
} catch (e) {
|
|
84
|
+
log.error('Failed to run eslint check', e)
|
|
85
|
+
return [
|
|
86
|
+
outdent`
|
|
87
|
+
Failed to run ESLint. Is ESLint configured?
|
|
88
|
+
It is recommended to install eslint-config-sanity and add 'sanity/upgrade-v2' to your eslint-extends config.
|
|
89
|
+
|
|
90
|
+
Run:
|
|
91
|
+
npm install --save-dev eslint-config-sanity
|
|
92
|
+
|
|
93
|
+
In .eslintrc add:
|
|
94
|
+
extends: ['sanity/upgrade-v2']
|
|
95
|
+
|
|
96
|
+
This way, V2-imports can be identified directly in the IDE, or using eslint CLI.
|
|
97
|
+
If the package does not use eslint, disable this check.
|
|
98
|
+
`,
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return []
|
|
103
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import execa from 'execa'
|
|
2
|
+
import {prompt} from '../util/prompt'
|
|
3
|
+
|
|
4
|
+
export function npmIsAvailable() {
|
|
5
|
+
return execa('npm', ['-v'])
|
|
6
|
+
.then(() => true)
|
|
7
|
+
.catch(() => false)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function yarnIsAvailable() {
|
|
11
|
+
return execa('yarn', ['-v'])
|
|
12
|
+
.then(() => true)
|
|
13
|
+
.catch(() => false)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function pnpmAvailable() {
|
|
17
|
+
return execa('pnpm', ['-v'])
|
|
18
|
+
.then(() => true)
|
|
19
|
+
.catch(() => false)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function promptForPackageManager() {
|
|
23
|
+
const [npm, yarn, pnpm] = await Promise.all([
|
|
24
|
+
npmIsAvailable(),
|
|
25
|
+
yarnIsAvailable(),
|
|
26
|
+
pnpmAvailable(),
|
|
27
|
+
])
|
|
28
|
+
|
|
29
|
+
const choices = [npm && 'npm', yarn && 'yarn', pnpm && 'pnpm'].filter(Boolean)
|
|
30
|
+
if (choices.length < 2) {
|
|
31
|
+
return choices[0] || 'npm'
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return prompt('Which package manager do you prefer?', {
|
|
35
|
+
choices: choices.map((value) => ({value, name: value})),
|
|
36
|
+
default: choices[0],
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function installDependencies(pm: string, {cwd}: {cwd?: string}) {
|
|
41
|
+
const proc = execa(pm, ['install'], {cwd, stdio: 'inherit'})
|
|
42
|
+
const {exitCode} = await proc
|
|
43
|
+
return exitCode <= 0
|
|
44
|
+
}
|