mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-30 03:39:11 +00:00
Compare commits
26 Commits
@vercel/ne
...
@vercel/no
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6ec53d9d3 | ||
|
|
3ad5903f70 | ||
|
|
3cf155e999 | ||
|
|
d9a298d97c | ||
|
|
487d3c8554 | ||
|
|
9d0bfd3656 | ||
|
|
ec75333569 | ||
|
|
51aab912a2 | ||
|
|
670b2653c0 | ||
|
|
f71686fdad | ||
|
|
ec9c8ce150 | ||
|
|
a2048fc6d3 | ||
|
|
09ff9cda9f | ||
|
|
3a4d6f7848 | ||
|
|
9a0d676c0d | ||
|
|
25cd7b9e6e | ||
|
|
f926d5516c | ||
|
|
4603383850 | ||
|
|
c0c57889c8 | ||
|
|
85908a0524 | ||
|
|
503b9a2429 | ||
|
|
eac8f32ae7 | ||
|
|
3f76fefde6 | ||
|
|
79ddc5746b | ||
|
|
9a14615b43 | ||
|
|
6d6ccbdc25 |
9
.github/CONTRIBUTING.md
vendored
9
.github/CONTRIBUTING.md
vendored
@@ -94,12 +94,3 @@ Sometimes you want to test changes to a Builder against an existing project, may
|
||||
4. Run `vercel *.tgz` to upload the tarball file and get a URL
|
||||
5. Edit any existing `vercel.json` project and replace `use` with the URL
|
||||
6. Run `vercel` or `vercel dev` to deploy with the experimental Builder
|
||||
|
||||
## Add a New Framework
|
||||
|
||||
You can add support for a new Framework by creating a Pull Request for this repository and following the steps below:
|
||||
|
||||
1. Add the Framework to the `@vercel/frameworks` package: The file is located in `./packages/frameworks/frameworks.json`. You can copy the structure of an existing one and adjust the required fields. Note that the `settings` property either contains a `value` or a `placeholder`. The `value` property is used when something is not configurable, the `placeholder` is used when something is configurable and can be changed with configuration. An example would be the Output Directory for Hugo, it's `public` by default but can be changed through its config file, so we use `placeholder` with an explanation of what can be used.
|
||||
2. Add an example to the `./examples` directory: The name of the directory should equal the slug of the framework used in `@vercel/frameworks`. The `.github/EXAMPLE_README_TEMPLATE.md` file can be used to create a `README.md` file for the example.
|
||||
3. Update the `@vercel/static-build` package: The file `./packages/now-static-build/src/frameworks.ts` has to be extended. You can add default routes that will always be applied to projects that use this Framework or specify some paths that will be cached to speed up the build process.
|
||||
4. After your Pull Request has been merged and released, other users can select the example on the Vercel dashboard and deploy it.
|
||||
|
||||
@@ -6,5 +6,5 @@ You're running Vercel CLI in a non-terminal context and there are no credentials
|
||||
|
||||
#### Possible Ways to Fix It
|
||||
|
||||
- Specify a value for the `--token` flag (this needs to be the token of the user account as which you'd like to act). You can either get the token from the `./vercel/auth.json` file located in your user directory or [from the dashboard](https://vercel.com/account/tokens).
|
||||
- Ensure that both `~/vercel/auth.json` and `~/vercel/config.json` exist
|
||||
- Specify a value for the `--token` flag (this needs to be the token of the user account as which you'd like to act). You can create a new token on your [Settings page](https://vercel.com/account/tokens).
|
||||
- Run `vercel login` to sign in and generate a new token
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { NowRequest, NowResponse } from '@now/node';
|
||||
import { NowRequest, NowResponse } from '@vercel/node';
|
||||
|
||||
export default (_req: NowRequest, res: NowResponse) => {
|
||||
const date = new Date().toString();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"react-helmet": "^5.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@now/node": "^1.3.0"
|
||||
"@vercel/node": "1.8.5"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "gatsby develop",
|
||||
|
||||
@@ -1107,15 +1107,6 @@
|
||||
"@nodelib/fs.scandir" "2.1.3"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@now/node@^1.3.0":
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@now/node/-/node-1.7.1.tgz#764a0c6bcb24967f8014c4f73ad238c292996fe3"
|
||||
integrity sha512-+srVKopsVTPDR3u9eOjJryZroLTrPp8XEOuIDGBdfFcJuS7qpAomctSbfyA7WNyjC0ExtUxELqBg5sAedG5+2g==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
ts-node "8.9.1"
|
||||
typescript "3.9.3"
|
||||
|
||||
"@pieh/friendly-errors-webpack-plugin@1.7.0-chalk-2":
|
||||
version "1.7.0-chalk-2"
|
||||
resolved "https://registry.yarnpkg.com/@pieh/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.0-chalk-2.tgz#2e9da9d3ade9d18d013333eb408c457d04eabac0"
|
||||
@@ -1409,6 +1400,15 @@
|
||||
dependencies:
|
||||
wonka "^4.0.14"
|
||||
|
||||
"@vercel/node@1.8.5":
|
||||
version "1.8.5"
|
||||
resolved "https://registry.yarnpkg.com/@vercel/node/-/node-1.8.5.tgz#2c8b9532f1bb25734a9964c52973386ed78022d4"
|
||||
integrity sha512-1iw7FSR8Oau6vZB1MWfBnA5q2a/IqRHiSZSbt8lz0dyTF599q8pc5GcSv/TvmrYaEGzh3+N0S4cbmuMCqVlwJg==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
ts-node "8.9.1"
|
||||
typescript "3.9.3"
|
||||
|
||||
"@webassemblyjs/ast@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/build-utils",
|
||||
"version": "2.6.1-canary.0",
|
||||
"version": "2.6.1-canary.2",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
|
||||
@@ -43,9 +43,8 @@ export function sortFiles(fileA: string, fileB: string) {
|
||||
export function detectApiExtensions(builders: Builder[]): Set<string> {
|
||||
return new Set<string>(
|
||||
builders
|
||||
.filter(
|
||||
b =>
|
||||
b.config && b.config.zeroConfig && b.src && b.src.startsWith('api/')
|
||||
.filter((b): b is Builder & { src: string } =>
|
||||
Boolean(b.config && b.config.zeroConfig && b.src?.startsWith('api/'))
|
||||
)
|
||||
.map(b => extname(b.src))
|
||||
.filter(Boolean)
|
||||
@@ -56,22 +55,28 @@ export function detectApiDirectory(builders: Builder[]): string | null {
|
||||
// TODO: We eventually want to save the api directory to
|
||||
// builder.config.apiDirectory so it is only detected once
|
||||
const found = builders.some(
|
||||
b => b.config && b.config.zeroConfig && b.src.startsWith('api/')
|
||||
b => b.config && b.config.zeroConfig && b.src?.startsWith('api/')
|
||||
);
|
||||
return found ? 'api' : null;
|
||||
}
|
||||
|
||||
// TODO: Replace this function with `config.outputDirectory`
|
||||
function getPublicBuilder(builders: Builder[]): Builder | null {
|
||||
const builder = builders.find(
|
||||
builder =>
|
||||
function getPublicBuilder(
|
||||
builders: Builder[]
|
||||
): (Builder & { src: string }) | null {
|
||||
for (const builder of builders) {
|
||||
if (
|
||||
typeof builder.src === 'string' &&
|
||||
isOfficialRuntime('static', builder.use) &&
|
||||
/^.*\/\*\*\/\*$/.test(builder.src) &&
|
||||
builder.config &&
|
||||
builder.config.zeroConfig === true
|
||||
);
|
||||
) {
|
||||
return builder as Builder & { src: string };
|
||||
}
|
||||
}
|
||||
|
||||
return builder || null;
|
||||
return null;
|
||||
}
|
||||
export function detectOutputDirectory(builders: Builder[]): string | null {
|
||||
// TODO: We eventually want to save the output directory to
|
||||
@@ -361,7 +366,7 @@ function maybeGetApiBuilder(
|
||||
return null;
|
||||
}
|
||||
|
||||
const match = apiMatches.find(({ src }) => {
|
||||
const match = apiMatches.find(({ src = '**' }) => {
|
||||
return src === fileName || minimatch(fileName, src);
|
||||
});
|
||||
|
||||
|
||||
@@ -292,6 +292,11 @@ export async function runNpmInstall(
|
||||
opts.prettyCommand = 'yarn install';
|
||||
command = 'yarn';
|
||||
commandArgs = ['install', ...args];
|
||||
|
||||
// Yarn v2 PnP mode may be activated, so force "node-modules" linker style
|
||||
if (!env.YARN_NODE_LINKER) {
|
||||
env.YARN_NODE_LINKER = 'node-modules';
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.NPM_ONLY_PRODUCTION) {
|
||||
@@ -388,10 +393,17 @@ export async function runPackageJsonScript(
|
||||
prettyCommand,
|
||||
});
|
||||
} else {
|
||||
// Yarn v2 PnP mode may be activated, so force "node-modules" linker style
|
||||
const env: typeof process.env = { ...spawnOpts?.env };
|
||||
if (!env.YARN_NODE_LINKER) {
|
||||
env.YARN_NODE_LINKER = 'node-modules';
|
||||
}
|
||||
|
||||
const prettyCommand = `yarn run ${scriptName}`;
|
||||
console.log(`Running "${prettyCommand}"`);
|
||||
await spawnAsync('yarn', ['run', scriptName], {
|
||||
...spawnOpts,
|
||||
env,
|
||||
cwd: destPath,
|
||||
prettyCommand,
|
||||
});
|
||||
|
||||
@@ -336,7 +336,7 @@ export interface NodeVersion {
|
||||
|
||||
export interface Builder {
|
||||
use: string;
|
||||
src: string;
|
||||
src?: string;
|
||||
config?: Config;
|
||||
}
|
||||
|
||||
|
||||
5
packages/now-build-utils/test/fixtures/19-yarn-v2/api/index.js
vendored
Normal file
5
packages/now-build-utils/test/fixtures/19-yarn-v2/api/index.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const { camelCase } = require('camel-case');
|
||||
|
||||
module.exports = (req, res) => {
|
||||
res.end(camelCase('camel-case module is working'));
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [{ "src": "package.json", "use": "@vercel/static-build" }],
|
||||
"probes": [{ "path": "/", "mustContain": "Svelte app" }]
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
"svelte": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"camel-case": "^4.1.2",
|
||||
"sirv-cli": "^0.4.4"
|
||||
}
|
||||
}
|
||||
|
||||
11
packages/now-build-utils/test/fixtures/19-yarn-v2/vercel.json
vendored
Normal file
11
packages/now-build-utils/test/fixtures/19-yarn-v2/vercel.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "package.json", "use": "@vercel/static-build" },
|
||||
{ "src": "api/index.js", "use": "@vercel/node" }
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "Svelte app" },
|
||||
{ "path": "/api", "mustContain": "camelCaseModuleIsWorking" }
|
||||
]
|
||||
}
|
||||
@@ -270,6 +270,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"camel-case@npm:^4.1.2":
|
||||
version: 4.1.2
|
||||
resolution: "camel-case@npm:4.1.2"
|
||||
dependencies:
|
||||
pascal-case: ^3.1.2
|
||||
tslib: ^2.0.3
|
||||
checksum: 3/0b8dcfb424c9497e45984b88ef005c66bdf8e877e36365aedfc3cf73182684fde5a14cf2c526579c0351a5f27dc39a00f1edecc25d43606075fea948c504e37f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"caseless@npm:~0.12.0":
|
||||
version: 0.12.0
|
||||
resolution: "caseless@npm:0.12.0"
|
||||
@@ -850,6 +860,15 @@ fsevents@~2.1.2:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lower-case@npm:^2.0.2":
|
||||
version: 2.0.2
|
||||
resolution: "lower-case@npm:2.0.2"
|
||||
dependencies:
|
||||
tslib: ^2.0.3
|
||||
checksum: 3/aabaca9cef65f7564a1005b625664527e4d169e363101e65773f8f6ff2fdcf09884a3bc02990cd7a62cf05f3538114af25ee7bef553f1ca3208c8a77ac75cbfa
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"magic-string@npm:^0.25.2":
|
||||
version: 0.25.7
|
||||
resolution: "magic-string@npm:0.25.7"
|
||||
@@ -944,6 +963,16 @@ fsevents@~2.1.2:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"no-case@npm:^3.0.4":
|
||||
version: 3.0.4
|
||||
resolution: "no-case@npm:3.0.4"
|
||||
dependencies:
|
||||
lower-case: ^2.0.2
|
||||
tslib: ^2.0.3
|
||||
checksum: 3/84db4909caec37504c6655f995a004067f8733be8cd8d849f1578661b60a1685e086325fa4e1a5e8ce94e7416c1d0f037e2a00f635a14457183de80ab4fc7612
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"node-gyp@npm:latest":
|
||||
version: 6.1.0
|
||||
resolution: "node-gyp@npm:6.1.0"
|
||||
@@ -1057,6 +1086,16 @@ fsevents@~2.1.2:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pascal-case@npm:^3.1.2":
|
||||
version: 3.1.2
|
||||
resolution: "pascal-case@npm:3.1.2"
|
||||
dependencies:
|
||||
no-case: ^3.0.4
|
||||
tslib: ^2.0.3
|
||||
checksum: 3/31708cecab221482edc81e2bd9b9d8282d72d4f1443b31f39725aa23768c5e42d93c4c014f1bc90f7f074e2a70d5091e4892ea370e550affc9ccf1d33c900bcd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"path-is-absolute@npm:^1.0.0":
|
||||
version: 1.0.1
|
||||
resolution: "path-is-absolute@npm:1.0.1"
|
||||
@@ -1447,6 +1486,7 @@ fsevents@~2.1.2:
|
||||
dependencies:
|
||||
"@rollup/plugin-commonjs": ^12.0.0
|
||||
"@rollup/plugin-node-resolve": ^8.0.0
|
||||
camel-case: ^4.1.2
|
||||
rollup: ^2.3.4
|
||||
rollup-plugin-livereload: ^1.0.0
|
||||
rollup-plugin-svelte: ^5.0.3
|
||||
@@ -1517,6 +1557,13 @@ fsevents@~2.1.2:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tslib@npm:^2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "tslib@npm:2.0.3"
|
||||
checksum: 3/447bfca5deaa157806c3f77eaba74d05dd0b38b014e47ce79d98b5c77ce7d91b00a687ba13ca1b5a74d35ca1098ac7a072c0a97fad06f0266612f2a03a6c8e8f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tunnel-agent@npm:^0.6.0":
|
||||
version: 0.6.0
|
||||
resolution: "tunnel-agent@npm:0.6.0"
|
||||
|
||||
@@ -182,7 +182,7 @@ describe('Test `detectBuilders`', () => {
|
||||
|
||||
const { builders } = await detectBuilders(files);
|
||||
expect(builders!.length).toBe(7);
|
||||
expect(builders!.some(b => b.src.endsWith('_test.go'))).toBe(false);
|
||||
expect(builders!.some(b => b.src!.endsWith('_test.go'))).toBe(false);
|
||||
});
|
||||
|
||||
it('just public', async () => {
|
||||
@@ -1341,7 +1341,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
featHandleMiss,
|
||||
});
|
||||
expect(builders!.length).toBe(7);
|
||||
expect(builders!.some(b => b.src.endsWith('_test.go'))).toBe(false);
|
||||
expect(builders!.some(b => b.src!.endsWith('_test.go'))).toBe(false);
|
||||
expect(errorRoutes!.length).toBe(1);
|
||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vercel",
|
||||
"version": "21.0.2-canary.1",
|
||||
"version": "21.0.2-canary.6",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Vercel",
|
||||
@@ -61,9 +61,9 @@
|
||||
"node": ">= 10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "2.6.1-canary.0",
|
||||
"@vercel/build-utils": "2.6.1-canary.2",
|
||||
"@vercel/go": "1.1.6",
|
||||
"@vercel/node": "1.8.6-canary.0",
|
||||
"@vercel/node": "1.8.6-canary.3",
|
||||
"@vercel/python": "1.2.3",
|
||||
"@vercel/ruby": "1.2.4",
|
||||
"update-notifier": "4.1.0"
|
||||
|
||||
@@ -324,7 +324,7 @@ function printLogRaw(log) {
|
||||
|
||||
if (log.object) {
|
||||
console.log(log.object);
|
||||
} else {
|
||||
} else if (typeof log.text === 'string') {
|
||||
console.log(
|
||||
log.text
|
||||
.replace(/\n$/, '')
|
||||
|
||||
@@ -402,7 +402,7 @@ export async function getBuildMatches(
|
||||
const builds = nowConfig.builds || [{ src: '**', use: '@vercel/static' }];
|
||||
|
||||
for (const buildConfig of builds) {
|
||||
let { src, use } = buildConfig;
|
||||
let { src = '**', use } = buildConfig;
|
||||
|
||||
if (!use) {
|
||||
continue;
|
||||
|
||||
@@ -50,6 +50,7 @@ export interface EnvConfigs {
|
||||
|
||||
export interface BuildMatch extends BuildConfig {
|
||||
entrypoint: string;
|
||||
src: string;
|
||||
builderWithPkg: BuilderWithPackage;
|
||||
buildOutput: BuilderOutputs;
|
||||
buildResults: Map<string | null, BuildResult>;
|
||||
|
||||
4
packages/now-cli/test/dev/fixtures/missing-src-property/.gitignore
vendored
Normal file
4
packages/now-cli/test/dev/fixtures/missing-src-property/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
package.json
|
||||
yarn.lock
|
||||
.now
|
||||
.vercel
|
||||
@@ -0,0 +1 @@
|
||||
hello:index.txt
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"builds": [
|
||||
{
|
||||
"use": "@vercel/static"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1756,3 +1756,11 @@ test(
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
test(
|
||||
'[vercel dev] Do not fail if `src` is missing',
|
||||
testFixtureStdio('missing-src-property', async testPath => {
|
||||
await testPath(200, '/', /hello:index.txt/m);
|
||||
await testPath(404, '/i-do-not-exist');
|
||||
})
|
||||
);
|
||||
|
||||
33
packages/now-cli/test/integration.js
vendored
33
packages/now-cli/test/integration.js
vendored
@@ -1566,7 +1566,7 @@ test('ensure we render a warning for deployments with no files', async t => {
|
||||
t.is(res.status, 404);
|
||||
});
|
||||
|
||||
test('output logs of a 2.0 deployment', async t => {
|
||||
test('output logs with "short" output', async t => {
|
||||
const { stderr, stdout, exitCode } = await execa(
|
||||
binaryPath,
|
||||
['logs', context.deployment, ...defaultArgs],
|
||||
@@ -1583,13 +1583,21 @@ test('output logs of a 2.0 deployment', async t => {
|
||||
stderr.includes(`Fetched deployment "${context.deployment}"`),
|
||||
formatOutput({ stderr, stdout })
|
||||
);
|
||||
|
||||
// "short" format includes timestamps
|
||||
t.truthy(
|
||||
stdout.match(
|
||||
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/
|
||||
)
|
||||
);
|
||||
|
||||
t.is(exitCode, 0);
|
||||
});
|
||||
|
||||
test('output logs of a 2.0 deployment without annotate', async t => {
|
||||
test('output logs with "raw" output', async t => {
|
||||
const { stderr, stdout, exitCode } = await execa(
|
||||
binaryPath,
|
||||
['logs', context.deployment, ...defaultArgs],
|
||||
['logs', context.deployment, ...defaultArgs, '--output', 'raw'],
|
||||
{
|
||||
reject: false,
|
||||
}
|
||||
@@ -1599,12 +1607,19 @@ test('output logs of a 2.0 deployment without annotate', async t => {
|
||||
console.log(stdout);
|
||||
console.log(exitCode);
|
||||
|
||||
t.true(!stderr.includes('[now-builder-debug]'));
|
||||
t.true(!stderr.includes('START RequestId'));
|
||||
t.true(!stderr.includes('END RequestId'));
|
||||
t.true(!stderr.includes('REPORT RequestId'));
|
||||
t.true(!stderr.includes('Init Duration'));
|
||||
t.true(!stderr.includes('XRAY TraceId'));
|
||||
t.true(
|
||||
stderr.includes(`Fetched deployment "${context.deployment}"`),
|
||||
formatOutput({ stderr, stdout })
|
||||
);
|
||||
|
||||
// "raw" format does not include timestamps
|
||||
t.is(
|
||||
null,
|
||||
stdout.match(
|
||||
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/
|
||||
)
|
||||
);
|
||||
|
||||
t.is(exitCode, 0);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/client",
|
||||
"version": "9.0.5-canary.0",
|
||||
"version": "9.0.5-canary.2",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"homepage": "https://vercel.com",
|
||||
@@ -37,7 +37,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "2.6.1-canary.0",
|
||||
"@vercel/build-utils": "2.6.1-canary.2",
|
||||
"@zeit/fetch": "5.2.0",
|
||||
"async-retry": "1.2.3",
|
||||
"async-sema": "3.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/next",
|
||||
"version": "2.7.6",
|
||||
"version": "2.7.8-canary.0",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
|
||||
@@ -26,7 +26,7 @@
|
||||
"@types/resolve-from": "5.0.1",
|
||||
"@types/semver": "6.0.0",
|
||||
"@types/yazl": "2.4.1",
|
||||
"@vercel/nft": "0.9.4",
|
||||
"@vercel/nft": "0.9.5",
|
||||
"async-sema": "3.0.1",
|
||||
"buffer-crc32": "0.2.13",
|
||||
"escape-string-regexp": "2.0.0",
|
||||
|
||||
@@ -381,6 +381,14 @@ export async function build({
|
||||
console.log(`Running "install" command: \`${installCommand}\`...`);
|
||||
await execCommand(installCommand, {
|
||||
...spawnOpts,
|
||||
|
||||
// Yarn v2 PnP mode may be activated, so force
|
||||
// "node-modules" linker style
|
||||
env: {
|
||||
YARN_NODE_LINKER: 'node-modules',
|
||||
...spawnOpts.env,
|
||||
},
|
||||
|
||||
cwd: entryPath,
|
||||
});
|
||||
} else {
|
||||
@@ -410,7 +418,7 @@ export async function build({
|
||||
}
|
||||
|
||||
const memoryToConsume = Math.floor(os.totalmem() / 1024 ** 2) - 128;
|
||||
const env: { [key: string]: string | undefined } = { ...spawnOpts.env };
|
||||
const env: typeof process.env = { ...spawnOpts.env };
|
||||
env.NODE_OPTIONS = `--max_old_space_size=${memoryToConsume}`;
|
||||
|
||||
if (buildCommand) {
|
||||
@@ -418,6 +426,11 @@ export async function build({
|
||||
const nodeBinPath = await getNodeBinPath({ cwd: entryPath });
|
||||
env.PATH = `${nodeBinPath}${path.delimiter}${env.PATH}`;
|
||||
|
||||
// Yarn v2 PnP mode may be activated, so force "node-modules" linker style
|
||||
if (!env.YARN_NODE_LINKER) {
|
||||
env.YARN_NODE_LINKER = 'node-modules';
|
||||
}
|
||||
|
||||
debug(
|
||||
`Added "${nodeBinPath}" to PATH env because a build command was used.`
|
||||
);
|
||||
@@ -1024,7 +1037,7 @@ export async function build({
|
||||
|
||||
if (
|
||||
initialRevalidate === false &&
|
||||
!canUsePreviewMode &&
|
||||
(!canUsePreviewMode || (hasPages404 && routeKey === '/404')) &&
|
||||
!prerenderManifest.fallbackRoutes[route] &&
|
||||
!prerenderManifest.blockingFallbackRoutes[route]
|
||||
) {
|
||||
@@ -1076,19 +1089,25 @@ export async function build({
|
||||
console.time(tracingLabel);
|
||||
}
|
||||
|
||||
const nftCache = Object.create(null);
|
||||
|
||||
const {
|
||||
fileList: apiFileList,
|
||||
reasons: apiReasons,
|
||||
} = await nodeFileTrace(apiPages, {
|
||||
base: baseDir,
|
||||
processCwd: entryPath,
|
||||
cache: nftCache,
|
||||
});
|
||||
|
||||
debug(`node-file-trace result for api routes: ${apiFileList}`);
|
||||
|
||||
const { fileList, reasons: nonApiReasons } = await nodeFileTrace(
|
||||
nonApiPages,
|
||||
{
|
||||
base: baseDir,
|
||||
processCwd: entryPath,
|
||||
cache: nftCache,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1812,7 +1831,11 @@ export async function build({
|
||||
});
|
||||
}
|
||||
|
||||
if (!canUsePreviewMode) {
|
||||
// If revalidate isn't enabled we force the /404 route to be static
|
||||
// to match next start behavior otherwise getStaticProps would be
|
||||
// recalled for each 404 URL path since Prerender is cached based
|
||||
// on the URL path
|
||||
if (!canUsePreviewMode || (hasPages404 && routeKey === '/404')) {
|
||||
htmlFsRef.contentType = htmlContentType;
|
||||
prerenders[outputPathPage] = htmlFsRef;
|
||||
prerenders[outputPathData] = jsonFsRef;
|
||||
@@ -2391,9 +2414,13 @@ export async function build({
|
||||
),
|
||||
|
||||
status: 404,
|
||||
headers: {
|
||||
'x-nextjs-page': page404Path,
|
||||
},
|
||||
...(static404Page
|
||||
? {}
|
||||
: {
|
||||
headers: {
|
||||
'x-nextjs-page': page404Path,
|
||||
},
|
||||
}),
|
||||
}
|
||||
: {
|
||||
src: path.join('/', entryDirectory, '.*'),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-env jest */
|
||||
const fetch = require('node-fetch');
|
||||
const cheerio = require('cheerio');
|
||||
const { check, waitFor } = require('../../utils');
|
||||
const fetch = require('../../../../../test/lib/deployment/fetch-retry');
|
||||
|
||||
async function checkForChange(url, initialValue, hardError) {
|
||||
return check(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-env jest */
|
||||
const fetch = require('node-fetch');
|
||||
const cheerio = require('cheerio');
|
||||
const { check, waitFor } = require('../../utils');
|
||||
const fetch = require('../../../../../test/lib/deployment/fetch-retry');
|
||||
|
||||
async function checkForChange(url, initialValue, hardError) {
|
||||
return check(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-env jest */
|
||||
const fetch = require('node-fetch');
|
||||
const cheerio = require('cheerio');
|
||||
const fetch = require('../../../../../test/lib/deployment/fetch-retry');
|
||||
|
||||
module.exports = function (ctx) {
|
||||
it('should revalidate content properly from pathname', async () => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-env jest */
|
||||
const cheerio = require('cheerio');
|
||||
const fetch = require('node-fetch');
|
||||
const setCookieParser = require('set-cookie-parser');
|
||||
const fetch = require('../../../../../test/lib/deployment/fetch-retry');
|
||||
|
||||
module.exports = function (ctx) {
|
||||
let previewCookie;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-env jest */
|
||||
const fetch = require('node-fetch');
|
||||
const cheerio = require('cheerio');
|
||||
const fetch = require('../../../../../test/lib/deployment/fetch-retry');
|
||||
|
||||
module.exports = function (ctx) {
|
||||
it('should revalidate content properly from dynamic pathname', async () => {
|
||||
|
||||
55
packages/now-next/test/fixtures/32-custom-install-command/.yarn/releases/yarn-berry.cjs
vendored
Executable file
55
packages/now-next/test/fixtures/32-custom-install-command/.yarn/releases/yarn-berry.cjs
vendored
Executable file
File diff suppressed because one or more lines are too long
1
packages/now-next/test/fixtures/32-custom-install-command/.yarnrc.yml
vendored
Normal file
1
packages/now-next/test/fixtures/32-custom-install-command/.yarnrc.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
yarnPath: ".yarn/releases/yarn-berry.cjs"
|
||||
5686
packages/now-next/test/fixtures/32-custom-install-command/yarn.lock
vendored
Normal file
5686
packages/now-next/test/fixtures/32-custom-install-command/yarn.lock
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
generateBuildId() {
|
||||
return 'testing-build-id';
|
||||
},
|
||||
};
|
||||
4
packages/now-next/test/integration/gip-gsp-404/now.json
Normal file
4
packages/now-next/test/integration/gip-gsp-404/now.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [{ "src": "package.json", "use": "@vercel/next" }]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"next": "canary",
|
||||
"react": "latest",
|
||||
"react-dom": "latest"
|
||||
}
|
||||
}
|
||||
13
packages/now-next/test/integration/gip-gsp-404/pages/404.js
Normal file
13
packages/now-next/test/integration/gip-gsp-404/pages/404.js
Normal file
@@ -0,0 +1,13 @@
|
||||
export default function MyApp() {
|
||||
return '404 page';
|
||||
}
|
||||
|
||||
export const getStaticProps = () => {
|
||||
console.log('/404 getStaticProps');
|
||||
return {
|
||||
props: {
|
||||
random: Math.random(),
|
||||
is404: true,
|
||||
},
|
||||
};
|
||||
};
|
||||
15
packages/now-next/test/integration/gip-gsp-404/pages/_app.js
Normal file
15
packages/now-next/test/integration/gip-gsp-404/pages/_app.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
return React.createElement(Component, pageProps);
|
||||
}
|
||||
|
||||
MyApp.getInitialProps = () => {
|
||||
console.log('App.getInitialProps');
|
||||
return {
|
||||
random: Math.random(),
|
||||
hello: 'world',
|
||||
};
|
||||
};
|
||||
|
||||
export default MyApp;
|
||||
@@ -0,0 +1,6 @@
|
||||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||
|
||||
export default (req, res) => {
|
||||
res.statusCode = 200;
|
||||
res.json({ name: 'John Doe' });
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function Home() {
|
||||
return 'index page';
|
||||
}
|
||||
@@ -34,6 +34,42 @@ it(
|
||||
FOUR_MINUTES
|
||||
);
|
||||
|
||||
it(
|
||||
'Should build the gip-gsp-404 example',
|
||||
async () => {
|
||||
const { buildResult } = await runBuildLambda(
|
||||
path.join(__dirname, 'gip-gsp-404')
|
||||
);
|
||||
const { output, routes } = buildResult;
|
||||
|
||||
const handleErrorIdx = (routes || []).findIndex(r => r.handle === 'error')
|
||||
expect(routes[handleErrorIdx + 1].dest).toBe('/404');
|
||||
expect(routes[handleErrorIdx + 1].headers).toBe(undefined);
|
||||
expect(output.goodbye).not.toBeDefined();
|
||||
expect(output.__NEXT_PAGE_LAMBDA_0).toBeDefined();
|
||||
expect(output['404']).toBeDefined();
|
||||
expect(output['404'].type).toBe('FileFsRef');
|
||||
expect(output['_next/data/testing-build-id/404.json']).toBeDefined();
|
||||
expect(output['_next/data/testing-build-id/404.json'].type).toBe(
|
||||
'FileFsRef'
|
||||
);
|
||||
const filePaths = Object.keys(output);
|
||||
const serverlessError = filePaths.some(filePath =>
|
||||
filePath.match(/_error/)
|
||||
);
|
||||
const hasUnderScoreAppStaticFile = filePaths.some(filePath =>
|
||||
filePath.match(/static.*\/pages\/_app-.*\.js$/)
|
||||
);
|
||||
const hasUnderScoreErrorStaticFile = filePaths.some(filePath =>
|
||||
filePath.match(/static.*\/pages\/_error-.*\.js$/)
|
||||
);
|
||||
expect(hasUnderScoreAppStaticFile).toBeTruthy();
|
||||
expect(hasUnderScoreErrorStaticFile).toBeTruthy();
|
||||
expect(serverlessError).toBeTruthy();
|
||||
},
|
||||
FOUR_MINUTES
|
||||
);
|
||||
|
||||
it(
|
||||
'Should not deploy preview lambdas for static site',
|
||||
async () => {
|
||||
|
||||
1
packages/now-node-bridge/.gitignore
vendored
1
packages/now-node-bridge/.gitignore
vendored
@@ -1 +1,2 @@
|
||||
/bridge.*
|
||||
/launcher.*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/node-bridge",
|
||||
"version": "1.3.1",
|
||||
"version": "1.3.2-canary.0",
|
||||
"license": "MIT",
|
||||
"main": "./index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -41,7 +41,7 @@ export function getNowLauncher({
|
||||
helpersPath,
|
||||
shouldAddHelpers = false,
|
||||
}: LauncherConfiguration) {
|
||||
return function(): Bridge {
|
||||
return function (): Bridge {
|
||||
let bridge = new Bridge();
|
||||
let isServerListening = false;
|
||||
|
||||
@@ -133,7 +133,7 @@ export function getAwsLauncher({
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
return function(e, context, callback) {
|
||||
return function (e, context, callback) {
|
||||
const { path, method: httpMethod, body, headers } = JSON.parse(e.body);
|
||||
const { query } = parse(path, true);
|
||||
const queryStringParameters: { [i: string]: string } = {};
|
||||
1
packages/now-node/.gitignore
vendored
1
packages/now-node/.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
/dist
|
||||
/src/bridge.ts
|
||||
/src/launcher.ts
|
||||
/test/fixtures/**/types.d.ts
|
||||
/test/fixtures/11-symlinks/symlink
|
||||
|
||||
@@ -1,31 +1,34 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
bridge_defs="$(dirname $(pwd))/now-node-bridge/src/bridge.ts"
|
||||
# Copy shared dependencies
|
||||
bridge_dir="$(dirname $(pwd))/now-node-bridge"
|
||||
cp -v "$bridge_dir/src/bridge.ts" "$bridge_dir/src/launcher.ts" src
|
||||
|
||||
cp -v "$bridge_defs" src
|
||||
# Start fresh
|
||||
rm -rf dist
|
||||
|
||||
# build ts files
|
||||
# Build TypeScript files
|
||||
tsc
|
||||
|
||||
# todo: improve
|
||||
# copy type file for ts test
|
||||
# TODO: improve
|
||||
# Copy type file for ts test
|
||||
cp dist/types.d.ts test/fixtures/15-helpers/ts/types.d.ts
|
||||
# setup symlink for symlink test
|
||||
ln -sf symlinked-asset test/fixtures/11-symlinks/symlink
|
||||
|
||||
# use types.d.ts as the main types export
|
||||
# Use types.d.ts as the main types export
|
||||
mv dist/types.d.ts dist/types
|
||||
rm dist/*.d.ts
|
||||
mv dist/types dist/index.d.ts
|
||||
|
||||
# bundle helpers.ts with ncc
|
||||
# Bundle helpers.ts with ncc
|
||||
rm dist/helpers.js
|
||||
ncc build src/helpers.ts -e @vercel/build-utils -e @now/build-utils -o dist/helpers
|
||||
mv dist/helpers/index.js dist/helpers.js
|
||||
rm -rf dist/helpers
|
||||
|
||||
# build source-map-support/register for source maps
|
||||
# Build source-map-support/register for source maps
|
||||
ncc build ../../node_modules/source-map-support/register -e @vercel/build-utils -e @now/build-utils -o dist/source-map-support
|
||||
mv dist/source-map-support/index.js dist/source-map-support.js
|
||||
rm -rf dist/source-map-support
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/node",
|
||||
"version": "1.8.6-canary.0",
|
||||
"version": "1.8.6-canary.3",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
|
||||
@@ -33,7 +33,7 @@
|
||||
"@types/etag": "1.8.0",
|
||||
"@types/test-listen": "1.1.0",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/nft": "0.9.4",
|
||||
"@vercel/nft": "0.9.5",
|
||||
"content-type": "1.0.4",
|
||||
"cookie": "0.4.0",
|
||||
"etag": "1.8.1",
|
||||
|
||||
@@ -1,20 +1,31 @@
|
||||
import { ServerResponse, IncomingMessage } from 'http';
|
||||
|
||||
export type NowRequestCookies = { [key: string]: string };
|
||||
export type NowRequestQuery = { [key: string]: string | string[] };
|
||||
export type VercelRequestCookies = { [key: string]: string };
|
||||
export type VercelRequestQuery = { [key: string]: string | string[] };
|
||||
export type VercelRequestBody = any;
|
||||
|
||||
export type VercelRequest = IncomingMessage & {
|
||||
query: VercelRequestQuery;
|
||||
cookies: VercelRequestCookies;
|
||||
body: VercelRequestBody;
|
||||
};
|
||||
|
||||
export type VercelResponse = ServerResponse & {
|
||||
send: (body: any) => VercelResponse;
|
||||
json: (jsonBody: any) => VercelResponse;
|
||||
status: (statusCode: number) => VercelResponse;
|
||||
redirect: (statusOrUrl: string | number, url?: string) => VercelResponse;
|
||||
};
|
||||
|
||||
export type VercelApiHandler = (
|
||||
req: VercelRequest,
|
||||
res: VercelResponse
|
||||
) => void;
|
||||
|
||||
// Backwards-compat
|
||||
export type NowRequestCookies = VercelRequestCookies;
|
||||
export type NowRequestQuery = VercelRequestQuery;
|
||||
export type NowRequestBody = any;
|
||||
|
||||
export type NowRequest = IncomingMessage & {
|
||||
query: NowRequestQuery;
|
||||
cookies: NowRequestCookies;
|
||||
body: NowRequestBody;
|
||||
};
|
||||
|
||||
export type NowResponse = ServerResponse & {
|
||||
send: (body: any) => NowResponse;
|
||||
json: (jsonBody: any) => NowResponse;
|
||||
status: (statusCode: number) => NowResponse;
|
||||
redirect: (statusOrUrl: string | number, url?: string) => NowResponse;
|
||||
};
|
||||
|
||||
export type NowApiHandler = (req: NowRequest, res: NowResponse) => void;
|
||||
export type NowRequest = VercelRequest;
|
||||
export type NowResponse = VercelResponse;
|
||||
export type NowApiHandler = VercelApiHandler;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"builds": [
|
||||
{ "src": "index.js", "use": "@vercel/node" },
|
||||
{ "src": "ts/index.ts", "use": "@vercel/node" },
|
||||
{ "src": "ts-legacy/index.ts", "use": "@vercel/node" },
|
||||
{ "src": "micro-compat/index.js", "use": "@vercel/node" },
|
||||
{
|
||||
"src": "no-helpers/index.js",
|
||||
@@ -40,6 +41,10 @@
|
||||
"path": "/ts",
|
||||
"mustContain": "hello:RANDOMNESS_PLACEHOLDER"
|
||||
},
|
||||
{
|
||||
"path": "/ts-legacy",
|
||||
"mustContain": "hello legacy:RANDOMNESS_PLACEHOLDER"
|
||||
},
|
||||
{
|
||||
"path": "/micro-compat",
|
||||
"method": "POST",
|
||||
|
||||
8
packages/now-node/test/fixtures/15-helpers/ts-legacy/handler.ts
vendored
Normal file
8
packages/now-node/test/fixtures/15-helpers/ts-legacy/handler.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import { NowApiHandler } from './types';
|
||||
|
||||
const listener: NowApiHandler = (req, res) => {
|
||||
res.status(200);
|
||||
res.send('hello legacy:RANDOMNESS_PLACEHOLDER');
|
||||
};
|
||||
|
||||
export default listener;
|
||||
6
packages/now-node/test/fixtures/15-helpers/ts-legacy/index.ts
vendored
Normal file
6
packages/now-node/test/fixtures/15-helpers/ts-legacy/index.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import { NowRequest, NowResponse } from './types';
|
||||
|
||||
export default function listener(req: NowRequest, res: NowResponse) {
|
||||
res.status(200);
|
||||
res.send('hello legacy:RANDOMNESS_PLACEHOLDER');
|
||||
}
|
||||
11
packages/now-node/test/fixtures/15-helpers/ts-legacy/tsconfig.json
vendored
Normal file
11
packages/now-node/test/fixtures/15-helpers/ts-legacy/tsconfig.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": true,
|
||||
"lib": ["esnext"],
|
||||
"target": "esnext",
|
||||
"module": "commonjs"
|
||||
},
|
||||
"include": ["index.ts", "handler.ts"]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NowApiHandler } from './types';
|
||||
import { VercelApiHandler } from './types';
|
||||
|
||||
const listener: NowApiHandler = (req, res) => {
|
||||
const listener: VercelApiHandler = (req, res) => {
|
||||
res.status(200);
|
||||
res.send('hello:RANDOMNESS_PLACEHOLDER');
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NowRequest, NowResponse } from './types';
|
||||
import { VercelRequest, VercelResponse } from './types';
|
||||
|
||||
export default function listener(req: NowRequest, res: NowResponse) {
|
||||
export default function listener(req: VercelRequest, res: VercelResponse) {
|
||||
res.status(200);
|
||||
res.send('hello:RANDOMNESS_PLACEHOLDER');
|
||||
}
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
"target": "esnext",
|
||||
"module": "commonjs"
|
||||
},
|
||||
"include": ["index.ts"]
|
||||
"include": ["index.ts", "handler.ts"]
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NowRequest, NowResponse } from '@now/node';
|
||||
import { hello } from './dep';
|
||||
|
||||
export default function(req: NowRequest, res: NowResponse) {
|
||||
export default function (req: NowRequest, res: NowResponse) {
|
||||
if (req) {
|
||||
res.end(hello.toString());
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/routing-utils",
|
||||
"version": "1.9.2-canary.3",
|
||||
"version": "1.9.2-canary.4",
|
||||
"description": "Vercel routing utilities",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
|
||||
@@ -5,42 +5,21 @@ export const routesSchema = {
|
||||
type: 'array',
|
||||
maxItems: 1024,
|
||||
items: {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
src: {
|
||||
type: 'string',
|
||||
maxLength: 4096,
|
||||
},
|
||||
dest: {
|
||||
type: 'string',
|
||||
maxLength: 4096,
|
||||
},
|
||||
methods: {
|
||||
type: 'array',
|
||||
maxItems: 10,
|
||||
items: {
|
||||
type: 'string',
|
||||
maxLength: 32,
|
||||
},
|
||||
},
|
||||
headers: {
|
||||
anyOf: [
|
||||
{
|
||||
type: 'object',
|
||||
required: ['src'],
|
||||
additionalProperties: false,
|
||||
minProperties: 1,
|
||||
maxProperties: 100,
|
||||
patternProperties: {
|
||||
'^.{1,256}$': {
|
||||
properties: {
|
||||
src: {
|
||||
type: 'string',
|
||||
maxLength: 4096,
|
||||
},
|
||||
},
|
||||
},
|
||||
locale: {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
redirect: {
|
||||
dest: {
|
||||
type: 'string',
|
||||
maxLength: 4096,
|
||||
},
|
||||
headers: {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
minProperties: 1,
|
||||
@@ -52,43 +31,78 @@ export const routesSchema = {
|
||||
},
|
||||
},
|
||||
},
|
||||
value: {
|
||||
type: 'string',
|
||||
maxLength: 4096,
|
||||
methods: {
|
||||
type: 'array',
|
||||
maxItems: 10,
|
||||
items: {
|
||||
type: 'string',
|
||||
maxLength: 32,
|
||||
},
|
||||
},
|
||||
path: {
|
||||
type: 'string',
|
||||
maxLength: 4096,
|
||||
important: {
|
||||
type: 'boolean',
|
||||
},
|
||||
cookie: {
|
||||
type: 'string',
|
||||
maxLength: 4096,
|
||||
continue: {
|
||||
type: 'boolean',
|
||||
},
|
||||
default: {
|
||||
type: 'string',
|
||||
maxLength: 4096,
|
||||
check: {
|
||||
type: 'boolean',
|
||||
},
|
||||
status: {
|
||||
type: 'integer',
|
||||
minimum: 100,
|
||||
maximum: 999,
|
||||
},
|
||||
locale: {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
minProperties: 1,
|
||||
properties: {
|
||||
redirect: {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
minProperties: 1,
|
||||
maxProperties: 100,
|
||||
patternProperties: {
|
||||
'^.{1,256}$': {
|
||||
type: 'string',
|
||||
maxLength: 4096,
|
||||
},
|
||||
},
|
||||
},
|
||||
value: {
|
||||
type: 'string',
|
||||
maxLength: 4096,
|
||||
},
|
||||
path: {
|
||||
type: 'string',
|
||||
maxLength: 4096,
|
||||
},
|
||||
cookie: {
|
||||
type: 'string',
|
||||
maxLength: 4096,
|
||||
},
|
||||
default: {
|
||||
type: 'string',
|
||||
maxLength: 4096,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
handle: {
|
||||
type: 'string',
|
||||
maxLength: 32,
|
||||
{
|
||||
type: 'object',
|
||||
required: ['handle'],
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
handle: {
|
||||
type: 'string',
|
||||
maxLength: 32,
|
||||
enum: ['error', 'filesystem', 'hit', 'miss', 'resource', 'rewrite'],
|
||||
},
|
||||
},
|
||||
},
|
||||
continue: {
|
||||
type: 'boolean',
|
||||
},
|
||||
check: {
|
||||
type: 'boolean',
|
||||
},
|
||||
important: {
|
||||
type: 'boolean',
|
||||
},
|
||||
status: {
|
||||
type: 'integer',
|
||||
minimum: 100,
|
||||
maximum: 999,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ export type Source = {
|
||||
important?: boolean;
|
||||
status?: number;
|
||||
locale?: {
|
||||
redirect: Record<string, string>;
|
||||
cookie: string;
|
||||
redirect?: Record<string, string>;
|
||||
cookie?: string;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
275
packages/now-routing-utils/test/index.spec.js
vendored
275
packages/now-routing-utils/test/index.spec.js
vendored
@@ -236,13 +236,25 @@ describe('normalizeRoutes', () => {
|
||||
],
|
||||
[
|
||||
{
|
||||
dataPath: '[0].src',
|
||||
keyword: 'type',
|
||||
dataPath: '[0].src',
|
||||
schemaPath: '#/items/anyOf/0/properties/src/type',
|
||||
params: { type: 'string' },
|
||||
message: 'should be string',
|
||||
params: {
|
||||
type: 'string',
|
||||
},
|
||||
schemaPath: '#/items/properties/src/type',
|
||||
},
|
||||
{
|
||||
keyword: 'additionalProperties',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/1/additionalProperties',
|
||||
params: { additionalProperty: 'src' },
|
||||
message: 'should NOT have additional properties',
|
||||
},
|
||||
{
|
||||
keyword: 'anyOf',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf',
|
||||
params: {},
|
||||
message: 'should match some schema in anyOf',
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -258,13 +270,25 @@ describe('normalizeRoutes', () => {
|
||||
],
|
||||
[
|
||||
{
|
||||
dataPath: '[0].dest',
|
||||
keyword: 'type',
|
||||
message: 'should be string',
|
||||
params: {
|
||||
type: 'string',
|
||||
},
|
||||
schemaPath: '#/items/properties/dest/type',
|
||||
keyword: 'required',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/0/required',
|
||||
params: { missingProperty: 'src' },
|
||||
message: "should have required property 'src'",
|
||||
},
|
||||
{
|
||||
keyword: 'additionalProperties',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/1/additionalProperties',
|
||||
params: { additionalProperty: 'dest' },
|
||||
message: 'should NOT have additional properties',
|
||||
},
|
||||
{
|
||||
keyword: 'anyOf',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf',
|
||||
params: {},
|
||||
message: 'should match some schema in anyOf',
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -280,13 +304,25 @@ describe('normalizeRoutes', () => {
|
||||
],
|
||||
[
|
||||
{
|
||||
dataPath: '[0].methods',
|
||||
keyword: 'type',
|
||||
message: 'should be array',
|
||||
params: {
|
||||
type: 'array',
|
||||
},
|
||||
schemaPath: '#/items/properties/methods/type',
|
||||
keyword: 'required',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/0/required',
|
||||
params: { missingProperty: 'src' },
|
||||
message: "should have required property 'src'",
|
||||
},
|
||||
{
|
||||
keyword: 'additionalProperties',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/1/additionalProperties',
|
||||
params: { additionalProperty: 'methods' },
|
||||
message: 'should NOT have additional properties',
|
||||
},
|
||||
{
|
||||
keyword: 'anyOf',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf',
|
||||
params: {},
|
||||
message: 'should match some schema in anyOf',
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -302,13 +338,25 @@ describe('normalizeRoutes', () => {
|
||||
],
|
||||
[
|
||||
{
|
||||
dataPath: '[0].methods[0]',
|
||||
keyword: 'type',
|
||||
message: 'should be string',
|
||||
params: {
|
||||
type: 'string',
|
||||
},
|
||||
schemaPath: '#/items/properties/methods/items/type',
|
||||
keyword: 'required',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/0/required',
|
||||
params: { missingProperty: 'src' },
|
||||
message: "should have required property 'src'",
|
||||
},
|
||||
{
|
||||
keyword: 'additionalProperties',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/1/additionalProperties',
|
||||
params: { additionalProperty: 'methods' },
|
||||
message: 'should NOT have additional properties',
|
||||
},
|
||||
{
|
||||
keyword: 'anyOf',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf',
|
||||
params: {},
|
||||
message: 'should match some schema in anyOf',
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -324,13 +372,25 @@ describe('normalizeRoutes', () => {
|
||||
],
|
||||
[
|
||||
{
|
||||
dataPath: '[0].headers',
|
||||
keyword: 'type',
|
||||
message: 'should be object',
|
||||
params: {
|
||||
type: 'object',
|
||||
},
|
||||
schemaPath: '#/items/properties/headers/type',
|
||||
keyword: 'required',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/0/required',
|
||||
params: { missingProperty: 'src' },
|
||||
message: "should have required property 'src'",
|
||||
},
|
||||
{
|
||||
keyword: 'additionalProperties',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/1/additionalProperties',
|
||||
params: { additionalProperty: 'headers' },
|
||||
message: 'should NOT have additional properties',
|
||||
},
|
||||
{
|
||||
keyword: 'anyOf',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf',
|
||||
params: {},
|
||||
message: 'should match some schema in anyOf',
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -348,14 +408,25 @@ describe('normalizeRoutes', () => {
|
||||
],
|
||||
[
|
||||
{
|
||||
dataPath: "[0].headers['test']",
|
||||
keyword: 'type',
|
||||
message: 'should be string',
|
||||
params: {
|
||||
type: 'string',
|
||||
},
|
||||
schemaPath:
|
||||
'#/items/properties/headers/patternProperties/%5E.%7B1%2C256%7D%24/type',
|
||||
keyword: 'required',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/0/required',
|
||||
params: { missingProperty: 'src' },
|
||||
message: "should have required property 'src'",
|
||||
},
|
||||
{
|
||||
keyword: 'additionalProperties',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/1/additionalProperties',
|
||||
params: { additionalProperty: 'headers' },
|
||||
message: 'should NOT have additional properties',
|
||||
},
|
||||
{
|
||||
keyword: 'anyOf',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf',
|
||||
params: {},
|
||||
message: 'should match some schema in anyOf',
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -371,13 +442,25 @@ describe('normalizeRoutes', () => {
|
||||
],
|
||||
[
|
||||
{
|
||||
dataPath: '[0].handle',
|
||||
keyword: 'additionalProperties',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/0/additionalProperties',
|
||||
params: { additionalProperty: 'handle' },
|
||||
message: 'should NOT have additional properties',
|
||||
},
|
||||
{
|
||||
keyword: 'type',
|
||||
dataPath: '[0].handle',
|
||||
schemaPath: '#/items/anyOf/1/properties/handle/type',
|
||||
params: { type: 'string' },
|
||||
message: 'should be string',
|
||||
params: {
|
||||
type: 'string',
|
||||
},
|
||||
schemaPath: '#/items/properties/handle/type',
|
||||
},
|
||||
{
|
||||
keyword: 'anyOf',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf',
|
||||
params: {},
|
||||
message: 'should match some schema in anyOf',
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -393,13 +476,25 @@ describe('normalizeRoutes', () => {
|
||||
],
|
||||
[
|
||||
{
|
||||
dataPath: '[0].continue',
|
||||
keyword: 'type',
|
||||
message: 'should be boolean',
|
||||
params: {
|
||||
type: 'boolean',
|
||||
},
|
||||
schemaPath: '#/items/properties/continue/type',
|
||||
keyword: 'required',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/0/required',
|
||||
params: { missingProperty: 'src' },
|
||||
message: "should have required property 'src'",
|
||||
},
|
||||
{
|
||||
keyword: 'additionalProperties',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/1/additionalProperties',
|
||||
params: { additionalProperty: 'continue' },
|
||||
message: 'should NOT have additional properties',
|
||||
},
|
||||
{
|
||||
keyword: 'anyOf',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf',
|
||||
params: {},
|
||||
message: 'should match some schema in anyOf',
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -415,13 +510,25 @@ describe('normalizeRoutes', () => {
|
||||
],
|
||||
[
|
||||
{
|
||||
dataPath: '[0].check',
|
||||
keyword: 'type',
|
||||
message: 'should be boolean',
|
||||
params: {
|
||||
type: 'boolean',
|
||||
},
|
||||
schemaPath: '#/items/properties/check/type',
|
||||
keyword: 'required',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/0/required',
|
||||
params: { missingProperty: 'src' },
|
||||
message: "should have required property 'src'",
|
||||
},
|
||||
{
|
||||
keyword: 'additionalProperties',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/1/additionalProperties',
|
||||
params: { additionalProperty: 'check' },
|
||||
message: 'should NOT have additional properties',
|
||||
},
|
||||
{
|
||||
keyword: 'anyOf',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf',
|
||||
params: {},
|
||||
message: 'should match some schema in anyOf',
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -437,13 +544,25 @@ describe('normalizeRoutes', () => {
|
||||
],
|
||||
[
|
||||
{
|
||||
dataPath: '[0].status',
|
||||
keyword: 'type',
|
||||
message: 'should be integer',
|
||||
params: {
|
||||
type: 'integer',
|
||||
},
|
||||
schemaPath: '#/items/properties/status/type',
|
||||
keyword: 'required',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/0/required',
|
||||
params: { missingProperty: 'src' },
|
||||
message: "should have required property 'src'",
|
||||
},
|
||||
{
|
||||
keyword: 'additionalProperties',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/1/additionalProperties',
|
||||
params: { additionalProperty: 'status' },
|
||||
message: 'should NOT have additional properties',
|
||||
},
|
||||
{
|
||||
keyword: 'anyOf',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf',
|
||||
params: {},
|
||||
message: 'should match some schema in anyOf',
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -459,13 +578,25 @@ describe('normalizeRoutes', () => {
|
||||
],
|
||||
[
|
||||
{
|
||||
dataPath: '[0]',
|
||||
keyword: 'additionalProperties',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/0/additionalProperties',
|
||||
params: { additionalProperty: 'doesNotExist' },
|
||||
message: 'should NOT have additional properties',
|
||||
params: {
|
||||
additionalProperty: 'doesNotExist',
|
||||
},
|
||||
schemaPath: '#/items/additionalProperties',
|
||||
},
|
||||
{
|
||||
keyword: 'additionalProperties',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf/1/additionalProperties',
|
||||
params: { additionalProperty: 'doesNotExist' },
|
||||
message: 'should NOT have additional properties',
|
||||
},
|
||||
{
|
||||
keyword: 'anyOf',
|
||||
dataPath: '[0]',
|
||||
schemaPath: '#/items/anyOf',
|
||||
params: {},
|
||||
message: 'should match some schema in anyOf',
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
set -euo pipefail
|
||||
|
||||
# Copy shared dependencies
|
||||
bridge_defs="$(dirname $(pwd))/now-node-bridge/src/bridge.ts"
|
||||
launcher_defs="$(dirname $(pwd))/now-node/src/launcher.ts"
|
||||
|
||||
cp -v "$bridge_defs" src
|
||||
cp -v "$launcher_defs" src
|
||||
bridge_dir="$(dirname $(pwd))/now-node-bridge"
|
||||
cp -v "$bridge_dir/src/bridge.ts" "$bridge_dir/src/launcher.ts" src
|
||||
|
||||
# Start fresh
|
||||
rm -rf dist
|
||||
|
||||
# Build TypeScript files
|
||||
tsc
|
||||
|
||||
# Build with `ncc`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/static-build",
|
||||
"version": "0.18.0",
|
||||
"version": "0.18.1-canary.1",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/build-step",
|
||||
|
||||
@@ -366,6 +366,14 @@ export async function build({
|
||||
console.log(`Running "install" command: \`${installCommand}\`...`);
|
||||
await execCommand(installCommand, {
|
||||
...spawnOpts,
|
||||
|
||||
// Yarn v2 PnP mode may be activated, so force
|
||||
// "node-modules" linker style
|
||||
env: {
|
||||
YARN_NODE_LINKER: 'node-modules',
|
||||
...spawnOpts.env,
|
||||
},
|
||||
|
||||
cwd: entrypointDir,
|
||||
});
|
||||
} else {
|
||||
@@ -468,6 +476,14 @@ export async function build({
|
||||
typeof buildCommand === 'string'
|
||||
? await execCommand(buildCommand, {
|
||||
...spawnOpts,
|
||||
|
||||
// Yarn v2 PnP mode may be activated, so force
|
||||
// "node-modules" linker style
|
||||
env: {
|
||||
YARN_NODE_LINKER: 'node-modules',
|
||||
...spawnOpts.env,
|
||||
},
|
||||
|
||||
cwd: entrypointDir,
|
||||
})
|
||||
: await runPackageJsonScript(
|
||||
|
||||
@@ -2,17 +2,11 @@
|
||||
set -euo pipefail
|
||||
|
||||
# Copy shared dependencies
|
||||
bridge_defs="$(dirname $(pwd))/now-node-bridge/src/bridge.ts"
|
||||
launcher_defs="$(dirname $(pwd))/now-node/src/launcher.ts"
|
||||
|
||||
cp -v "$bridge_defs" src
|
||||
cp -v "$launcher_defs" src
|
||||
bridge_dir="$(dirname $(pwd))/now-node-bridge"
|
||||
cp -v "$bridge_dir/src/bridge.ts" "$bridge_dir/src/launcher.ts" src
|
||||
|
||||
# Start fresh
|
||||
rm -rf dist
|
||||
|
||||
## Build ts files
|
||||
# Build TypeScript files
|
||||
tsc
|
||||
|
||||
# Build with `ncc`
|
||||
#ncc build src/index.ts -e @vercel/build-utils -e @now/build-utils -o dist
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/redwood",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1-canary.0",
|
||||
"main": "./dist/index.js",
|
||||
"license": "MIT",
|
||||
"homepage": "https://vercel.com/docs",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
const fetch = require('node-fetch');
|
||||
const retryBailByDefault = require('./retry-bail-by-default.js');
|
||||
|
||||
async function fetchRetry (...args) {
|
||||
async function fetchRetry(...args) {
|
||||
return await retryBailByDefault(
|
||||
async (canRetry) => {
|
||||
async canRetry => {
|
||||
try {
|
||||
return await fetch(...args);
|
||||
} catch (error) {
|
||||
@@ -14,6 +14,12 @@ async function fetchRetry (...args) {
|
||||
// request to https://api-gru1.vercel.com/v3/now/deployments/dpl_FBWWhpQomjgwjJLu396snLrGZYCm failed, reason:
|
||||
// connect ETIMEDOUT 18.228.143.224:443
|
||||
throw canRetry(error);
|
||||
} else if (error.code === 'ECONNREFUSED') {
|
||||
// request to https://test2020-dhdy1xrfa.vercel.app/blog/post-3 failed, reason:
|
||||
// connect ECONNREFUSED 76.76.21.21:443
|
||||
throw canRetry(error);
|
||||
} else if (error.code === 'ECONNRESET') {
|
||||
throw canRetry(error);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
14
yarn.lock
14
yarn.lock
@@ -2226,10 +2226,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@vercel/ncc/-/ncc-0.24.0.tgz#a2e8783a185caa99b5d8961a57dfc9665de16296"
|
||||
integrity sha512-crqItMcIwCkvdXY/V3/TzrHJQx6nbIaRqE1cOopJhgGX6izvNov40SmD//nS5flfEvdK54YGjwVVq+zG6crjOg==
|
||||
|
||||
"@vercel/nft@0.9.4":
|
||||
version "0.9.4"
|
||||
resolved "https://registry.yarnpkg.com/@vercel/nft/-/nft-0.9.4.tgz#43df00808e63fd1b04e7ac15898661985b48ff2c"
|
||||
integrity sha512-vy9i2A9oZDiYgznMXHSdzgHa1sc3bHVJ42DUpRe5jcxJl0eOGgSmulVWkDkuXIeWA7cqYzN/ofb21B/le2CDNg==
|
||||
"@vercel/nft@0.9.5":
|
||||
version "0.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@vercel/nft/-/nft-0.9.5.tgz#bf795944a4764ca49ca1a642f17ab32f9ac701d2"
|
||||
integrity sha512-EhSFOYwqvH3KZyK1pKyFj/DRoCZ2KFu8sRaVaJ+KGlU4kroAWm8okeA2EtIY11+/fMX3YQkNno7kf5H4FZrDvg==
|
||||
dependencies:
|
||||
acorn "^7.1.1"
|
||||
acorn-class-fields "^0.3.2"
|
||||
@@ -6266,9 +6266,9 @@ inherits@2.0.3:
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
|
||||
ini@^1.3.2, ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
||||
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
|
||||
version "1.3.7"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84"
|
||||
integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==
|
||||
|
||||
init-package-json@^1.10.3:
|
||||
version "1.10.3"
|
||||
|
||||
Reference in New Issue
Block a user