@jungvonmatt/contentful-ssg 1.0.4 → 1.0.5
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/dist/cli.js +12 -1
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/config.js +6 -6
- package/dist/lib/object.d.ts +2 -1
- package/dist/lib/object.js +8 -3
- package/package.json +6 -2
- package/src/cli.ts +29 -3
- package/src/lib/config.ts +23 -17
- package/src/lib/object.test.ts +16 -1
- package/src/lib/object.ts +14 -3
package/dist/cli.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import { existsSync } from 'fs';
|
|
5
|
+
import { readFile } from 'fs/promises';
|
|
5
6
|
import { outputFile } from 'fs-extra';
|
|
6
7
|
import prettier from 'prettier';
|
|
7
8
|
import { Command } from 'commander';
|
|
@@ -44,7 +45,17 @@ program
|
|
|
44
45
|
if (verified.directory?.startsWith('/')) {
|
|
45
46
|
verified.directory = path.relative(process.cwd(), verified.directory);
|
|
46
47
|
}
|
|
47
|
-
const environmentKeys = Object.keys(environmentConfig)
|
|
48
|
+
const environmentKeys = Object.keys(environmentConfig);
|
|
49
|
+
if (environmentConfig && existsSync('.env')) {
|
|
50
|
+
const envSource = await readFile('.env', 'utf8');
|
|
51
|
+
const nextEnvSource = envSource
|
|
52
|
+
.replace(/(CONTENTFUL_SPACE_ID\s*=\s*['"]?)[^'"]*(['"]?)/, `$1${verified.spaceId}$2`)
|
|
53
|
+
.replace(/(CONTENTFUL_ENVIRONMENT_ID\s*=\s*['"]?)[^'"]*(['"]?)/, `$1${verified.environmentId}$2`)
|
|
54
|
+
.replace(/(CONTENTFUL_MANAGEMENT_TOKEN\s*=\s*['"]?)[^'"]*(['"]?)/, `$1${verified.managementToken}$2`)
|
|
55
|
+
.replace(/(CONTENTFUL_PREVIEW_TOKEN\s*=\s*['"]?)[^'"]*(['"]?)/, `$1${verified.previewAccessToken}$2`)
|
|
56
|
+
.replace(/(CONTENTFUL_DELIVERY_TOKEN\s*=\s*['"]?)[^'"]*(['"]?)/, `$1${verified.accessToken}$2`);
|
|
57
|
+
await outputFile('.env', nextEnvSource);
|
|
58
|
+
}
|
|
48
59
|
const cleanedConfig = omitKeys(verified, 'preview', 'verbose', 'rootDir', 'resolvedPlugins', 'host', 'managementToken', ...environmentKeys);
|
|
49
60
|
let content = '';
|
|
50
61
|
if (useTypescript) {
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { Config, ContentfulConfig } from '../types.js';
|
|
2
|
-
export declare const getEnvironmentConfig: () => ContentfulConfig;
|
|
2
|
+
export declare const getEnvironmentConfig: (strict?: boolean) => ContentfulConfig;
|
|
3
3
|
export declare const getConfig: (args?: Partial<Config>) => Promise<Config>;
|
package/dist/lib/config.js
CHANGED
|
@@ -72,13 +72,13 @@ const loadConfig = async (moduleName) => {
|
|
|
72
72
|
});
|
|
73
73
|
return explorer.search();
|
|
74
74
|
};
|
|
75
|
-
export const getEnvironmentConfig = () => removeEmpty({
|
|
75
|
+
export const getEnvironmentConfig = (strict = true) => removeEmpty({
|
|
76
76
|
spaceId: process.env.CONTENTFUL_SPACE_ID,
|
|
77
77
|
environmentId: process.env.CONTENTFUL_ENVIRONMENT_ID,
|
|
78
78
|
managementToken: process.env.CONTENTFUL_MANAGEMENT_TOKEN,
|
|
79
79
|
previewAccessToken: process.env.CONTENTFUL_PREVIEW_TOKEN,
|
|
80
80
|
accessToken: process.env.CONTENTFUL_DELIVERY_TOKEN,
|
|
81
|
-
});
|
|
81
|
+
}, strict);
|
|
82
82
|
export const getConfig = async (args) => {
|
|
83
83
|
const defaultOptions = {
|
|
84
84
|
environmentId: 'master',
|
|
@@ -87,18 +87,18 @@ export const getConfig = async (args) => {
|
|
|
87
87
|
plugins: [],
|
|
88
88
|
resolvedPlugins: [],
|
|
89
89
|
};
|
|
90
|
-
const environmentOptions = getEnvironmentConfig();
|
|
90
|
+
const environmentOptions = getEnvironmentConfig(false);
|
|
91
91
|
let contentfulCliOptions = {};
|
|
92
92
|
try {
|
|
93
93
|
const contentfulConfig = await loadConfig('contentful');
|
|
94
|
-
if (!contentfulConfig.isEmpty) {
|
|
94
|
+
if (contentfulConfig && !contentfulConfig.isEmpty) {
|
|
95
95
|
const { managementToken, activeSpaceId, activeEnvironmentId, host } = contentfulConfig.config;
|
|
96
96
|
contentfulCliOptions = removeEmpty({
|
|
97
97
|
spaceId: activeSpaceId,
|
|
98
98
|
managementToken,
|
|
99
99
|
environmentId: activeEnvironmentId,
|
|
100
100
|
host,
|
|
101
|
-
});
|
|
101
|
+
}, false);
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
catch (error) {
|
|
@@ -116,7 +116,7 @@ export const getConfig = async (args) => {
|
|
|
116
116
|
args.rootDir = process.cwd();
|
|
117
117
|
try {
|
|
118
118
|
const configFile = await loadConfig('contentful-ssg');
|
|
119
|
-
if (!configFile.isEmpty) {
|
|
119
|
+
if (configFile && !configFile.isEmpty) {
|
|
120
120
|
configFileOptions = configFile.config;
|
|
121
121
|
args.rootDir = dirname(configFile.filepath);
|
|
122
122
|
if (configFileOptions.directory && !isAbsolute(configFileOptions.directory)) {
|
package/dist/lib/object.d.ts
CHANGED
|
@@ -5,7 +5,8 @@ export declare const isObject: (something: any) => boolean;
|
|
|
5
5
|
export declare const getEntries: <T>(obj: T) => Entries<T>;
|
|
6
6
|
export declare const fromEntries: <T = [string, unknown][]>(entries: Entries<T>) => T;
|
|
7
7
|
export declare const omitKeys: <T, K extends keyof T>(obj: T, ...keys: K[]) => T;
|
|
8
|
-
export declare const
|
|
8
|
+
export declare const filterKeys: <T, K extends keyof T>(obj: T, ...keys: K[]) => T;
|
|
9
|
+
export declare const removeEmpty: <T>(iterable: T, strict?: boolean) => T;
|
|
9
10
|
export declare const snakeCaseKeys: <T>(iterable: T) => T;
|
|
10
11
|
export declare const groupBy: <T extends Record<string, unknown>>(array: T[], key: keyof T) => Record<string, T[]>;
|
|
11
12
|
export {};
|
package/dist/lib/object.js
CHANGED
|
@@ -8,14 +8,19 @@ export const omitKeys = (obj, ...keys) => {
|
|
|
8
8
|
const filtered = entries.filter(([key]) => !keys.includes(key));
|
|
9
9
|
return fromEntries(filtered);
|
|
10
10
|
};
|
|
11
|
-
export const
|
|
11
|
+
export const filterKeys = (obj, ...keys) => {
|
|
12
|
+
const entries = getEntries(obj);
|
|
13
|
+
const filtered = entries.filter(([key]) => keys.includes(key));
|
|
14
|
+
return fromEntries(filtered);
|
|
15
|
+
};
|
|
16
|
+
export const removeEmpty = (iterable, strict = true) => {
|
|
12
17
|
if (Array.isArray(iterable)) {
|
|
13
18
|
return iterable
|
|
14
|
-
.filter((v) => v !== null && v !== undefined)
|
|
19
|
+
.filter((v) => v !== null && v !== undefined && (strict || Boolean(v)))
|
|
15
20
|
.map((v) => (v === Object(v) ? removeEmpty(v) : v));
|
|
16
21
|
}
|
|
17
22
|
return fromEntries(getEntries(iterable)
|
|
18
|
-
.filter(([, v]) => v !== null && v !== undefined)
|
|
23
|
+
.filter(([, v]) => v !== null && v !== undefined && (strict || Boolean(v)))
|
|
19
24
|
.map(([k, v]) => [k, v === Object(v) ? removeEmpty(v) : v]));
|
|
20
25
|
};
|
|
21
26
|
export const snakeCaseKeys = (iterable) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jungvonmatt/contentful-ssg",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
".": "./dist/index.js",
|
|
10
10
|
"./lib/object": "./dist/lib/object.js",
|
|
11
11
|
"./lib/array": "./dist/lib/array.js",
|
|
12
|
+
"./lib/utils": "./dist/lib/utils.js",
|
|
12
13
|
"./lib/contentful": "./dist/lib/contentful.js",
|
|
13
14
|
"./lib/hook-manager": "./dist/lib/hook-manager.js",
|
|
14
15
|
"./lib/file-manager": "./dist/lib/file-manager.js",
|
|
@@ -23,6 +24,9 @@
|
|
|
23
24
|
".": [
|
|
24
25
|
"./dist/types.d.ts"
|
|
25
26
|
],
|
|
27
|
+
"lib/utils": [
|
|
28
|
+
"./dist/lib/utils.d.ts"
|
|
29
|
+
],
|
|
26
30
|
"lib/object": [
|
|
27
31
|
"./dist/lib/object.d.ts"
|
|
28
32
|
],
|
|
@@ -139,5 +143,5 @@
|
|
|
139
143
|
"module": "es2020"
|
|
140
144
|
}
|
|
141
145
|
},
|
|
142
|
-
"gitHead": "
|
|
146
|
+
"gitHead": "03741b4add20ce95e1cd539bc46b7630cddcc2c3"
|
|
143
147
|
}
|
package/src/cli.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import chalk from 'chalk';
|
|
6
6
|
import { existsSync } from 'fs';
|
|
7
|
+
import { readFile } from 'fs/promises';
|
|
7
8
|
import { outputFile } from 'fs-extra';
|
|
8
9
|
import prettier from 'prettier';
|
|
9
10
|
import { Command } from 'commander';
|
|
@@ -67,9 +68,34 @@ program
|
|
|
67
68
|
verified.directory = path.relative(process.cwd(), verified.directory);
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
const environmentKeys: Array<keyof ContentfulConfig> = (
|
|
71
|
-
|
|
72
|
-
)
|
|
71
|
+
const environmentKeys: Array<keyof ContentfulConfig> = Object.keys(
|
|
72
|
+
environmentConfig
|
|
73
|
+
) as Array<keyof ContentfulConfig>;
|
|
74
|
+
|
|
75
|
+
// Update .env file
|
|
76
|
+
if (environmentConfig && existsSync('.env')) {
|
|
77
|
+
const envSource = await readFile('.env', 'utf8');
|
|
78
|
+
const nextEnvSource = envSource
|
|
79
|
+
.replace(/(CONTENTFUL_SPACE_ID\s*=\s*['"]?)[^'"]*(['"]?)/, `$1${verified.spaceId}$2`)
|
|
80
|
+
.replace(
|
|
81
|
+
/(CONTENTFUL_ENVIRONMENT_ID\s*=\s*['"]?)[^'"]*(['"]?)/,
|
|
82
|
+
`$1${verified.environmentId}$2`
|
|
83
|
+
)
|
|
84
|
+
.replace(
|
|
85
|
+
/(CONTENTFUL_MANAGEMENT_TOKEN\s*=\s*['"]?)[^'"]*(['"]?)/,
|
|
86
|
+
`$1${verified.managementToken}$2`
|
|
87
|
+
)
|
|
88
|
+
.replace(
|
|
89
|
+
/(CONTENTFUL_PREVIEW_TOKEN\s*=\s*['"]?)[^'"]*(['"]?)/,
|
|
90
|
+
`$1${verified.previewAccessToken}$2`
|
|
91
|
+
)
|
|
92
|
+
.replace(
|
|
93
|
+
/(CONTENTFUL_DELIVERY_TOKEN\s*=\s*['"]?)[^'"]*(['"]?)/,
|
|
94
|
+
`$1${verified.accessToken}$2`
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
await outputFile('.env', nextEnvSource);
|
|
98
|
+
}
|
|
73
99
|
|
|
74
100
|
const cleanedConfig = omitKeys(
|
|
75
101
|
verified,
|
package/src/lib/config.ts
CHANGED
|
@@ -105,14 +105,17 @@ const loadConfig = async (moduleName: string): Promise<CosmiconfigResult> => {
|
|
|
105
105
|
return explorer.search();
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
-
export const getEnvironmentConfig = (): ContentfulConfig =>
|
|
109
|
-
removeEmpty(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
108
|
+
export const getEnvironmentConfig = (strict = true): ContentfulConfig =>
|
|
109
|
+
removeEmpty(
|
|
110
|
+
{
|
|
111
|
+
spaceId: process.env.CONTENTFUL_SPACE_ID!,
|
|
112
|
+
environmentId: process.env.CONTENTFUL_ENVIRONMENT_ID!,
|
|
113
|
+
managementToken: process.env.CONTENTFUL_MANAGEMENT_TOKEN!,
|
|
114
|
+
previewAccessToken: process.env.CONTENTFUL_PREVIEW_TOKEN!,
|
|
115
|
+
accessToken: process.env.CONTENTFUL_DELIVERY_TOKEN!,
|
|
116
|
+
},
|
|
117
|
+
strict
|
|
118
|
+
);
|
|
116
119
|
|
|
117
120
|
/**
|
|
118
121
|
* Get configuration
|
|
@@ -127,22 +130,25 @@ export const getConfig = async (args?: Partial<Config>): Promise<Config> => {
|
|
|
127
130
|
resolvedPlugins: [],
|
|
128
131
|
};
|
|
129
132
|
|
|
130
|
-
const environmentOptions = getEnvironmentConfig();
|
|
133
|
+
const environmentOptions = getEnvironmentConfig(false);
|
|
131
134
|
let contentfulCliOptions: Partial<ContentfulConfig> = {};
|
|
132
135
|
|
|
133
136
|
try {
|
|
134
137
|
// Get configuration from contentful rc file (created by the contentful cli command)
|
|
135
138
|
const contentfulConfig = await loadConfig('contentful');
|
|
136
|
-
if (!contentfulConfig.isEmpty) {
|
|
139
|
+
if (contentfulConfig && !contentfulConfig.isEmpty) {
|
|
137
140
|
const { managementToken, activeSpaceId, activeEnvironmentId, host } =
|
|
138
141
|
contentfulConfig.config as ContentfulRcConfig;
|
|
139
142
|
|
|
140
|
-
contentfulCliOptions = removeEmpty(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
contentfulCliOptions = removeEmpty(
|
|
144
|
+
{
|
|
145
|
+
spaceId: activeSpaceId,
|
|
146
|
+
managementToken,
|
|
147
|
+
environmentId: activeEnvironmentId,
|
|
148
|
+
host,
|
|
149
|
+
},
|
|
150
|
+
false
|
|
151
|
+
);
|
|
146
152
|
}
|
|
147
153
|
} catch (error: unknown) {
|
|
148
154
|
if (typeof error === 'string') {
|
|
@@ -159,7 +165,7 @@ export const getConfig = async (args?: Partial<Config>): Promise<Config> => {
|
|
|
159
165
|
try {
|
|
160
166
|
// Get configuration from contentful-ssg rc file
|
|
161
167
|
const configFile = await loadConfig('contentful-ssg');
|
|
162
|
-
if (!configFile.isEmpty) {
|
|
168
|
+
if (configFile && !configFile.isEmpty) {
|
|
163
169
|
configFileOptions = configFile.config as Partial<Config>;
|
|
164
170
|
args.rootDir = dirname(configFile.filepath);
|
|
165
171
|
if (configFileOptions.directory && !isAbsolute(configFileOptions.directory)) {
|
package/src/lib/object.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
2
|
-
import { isObject, omitKeys, removeEmpty, snakeCaseKeys, groupBy } from './object';
|
|
2
|
+
import { isObject, omitKeys, filterKeys, removeEmpty, snakeCaseKeys, groupBy } from './object';
|
|
3
3
|
|
|
4
4
|
test('isObject', async () => {
|
|
5
5
|
const arr = [];
|
|
@@ -17,6 +17,11 @@ test('omitKeys', () => {
|
|
|
17
17
|
expect(value).toEqual({ b: 2 });
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
+
test('filterKeys', () => {
|
|
21
|
+
const value = filterKeys({ a: 1, b: 2, c: 3 }, 'a', 'c');
|
|
22
|
+
expect(value).toEqual({ a: 1, c: 3 });
|
|
23
|
+
});
|
|
24
|
+
|
|
20
25
|
test('removeEmpty', () => {
|
|
21
26
|
const value = removeEmpty({
|
|
22
27
|
a: { c: undefined },
|
|
@@ -26,6 +31,16 @@ test('removeEmpty', () => {
|
|
|
26
31
|
expect(value).toEqual({ a: {}, c: [1, { x: 1, z: [7] }, 3, 5] });
|
|
27
32
|
});
|
|
28
33
|
|
|
34
|
+
|
|
35
|
+
test('removeEmpty non-strict', () => {
|
|
36
|
+
const value = removeEmpty({
|
|
37
|
+
a: "",
|
|
38
|
+
b: 0,
|
|
39
|
+
c: 1,
|
|
40
|
+
}, false);
|
|
41
|
+
expect(value).toEqual({ c: 1 });
|
|
42
|
+
});
|
|
43
|
+
|
|
29
44
|
test('groupBy', () => {
|
|
30
45
|
const value = groupBy(
|
|
31
46
|
[
|
package/src/lib/object.ts
CHANGED
|
@@ -30,16 +30,27 @@ export const omitKeys = <T, K extends keyof T>(obj: T, ...keys: K[]): T => {
|
|
|
30
30
|
return fromEntries(filtered);
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Filter values by key from object
|
|
35
|
+
* @param {*} obj
|
|
36
|
+
* @param {*} keys
|
|
37
|
+
*/
|
|
38
|
+
export const filterKeys = <T, K extends keyof T>(obj: T, ...keys: K[]): T => {
|
|
39
|
+
const entries: Entries<T> = getEntries(obj);
|
|
40
|
+
const filtered = entries.filter(([key]) => keys.includes(key as K));
|
|
41
|
+
return fromEntries(filtered);
|
|
42
|
+
};
|
|
43
|
+
|
|
33
44
|
/**
|
|
34
45
|
* Recursive remove empty items (null,undefined) from object
|
|
35
46
|
* @param iterable Source object
|
|
36
47
|
* @returns Cleaned object
|
|
37
48
|
*/
|
|
38
|
-
export const removeEmpty = <T>(iterable: T): T => {
|
|
49
|
+
export const removeEmpty = <T>(iterable: T, strict = true): T => {
|
|
39
50
|
if (Array.isArray(iterable)) {
|
|
40
51
|
return (
|
|
41
52
|
iterable
|
|
42
|
-
.filter((v) => v !== null && v !== undefined)
|
|
53
|
+
.filter((v) => v !== null && v !== undefined && (strict || Boolean(v)))
|
|
43
54
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
44
55
|
.map((v) => (v === Object(v) ? removeEmpty(v) : v)) as unknown as T
|
|
45
56
|
);
|
|
@@ -47,7 +58,7 @@ export const removeEmpty = <T>(iterable: T): T => {
|
|
|
47
58
|
|
|
48
59
|
return fromEntries(
|
|
49
60
|
getEntries(iterable)
|
|
50
|
-
.filter(([, v]) => v !== null && v !== undefined)
|
|
61
|
+
.filter(([, v]) => v !== null && v !== undefined && (strict || Boolean(v)))
|
|
51
62
|
.map(([k, v]) => [k, v === Object(v) ? removeEmpty(v) : v])
|
|
52
63
|
);
|
|
53
64
|
};
|