@graphcommerce/hygraph-cli 9.0.0-canary.72 → 9.0.0-canary.74
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/CHANGELOG.md +4 -0
- package/Config.graphqls +6 -10
- package/dist/UpsertClient.js +69 -0
- package/dist/index.js +2 -2
- package/dist/migrateHygraphCli.js +111 -0
- package/dist/migrationActionFactory.js +133 -0
- package/dist/migrations/graphcommerce5to6.js +12 -14
- package/dist/migrations/graphcommerce6to7.js +25 -27
- package/dist/migrations/graphcommerce7to8.js +7 -9
- package/dist/migrations/graphcommerce8to9.js +54 -8
- package/dist/readSchema.js +10 -21
- package/dist/utils/getConfig.js +19 -0
- package/dist/utils/getEndpointUrl.js +43 -0
- package/dist/utils/getManagementClient.js +15 -0
- package/dist/{log-functions.js → utils/graphCommerceLog.js} +1 -1
- package/package.json +5 -5
- package/src/UpsertClient.ts +99 -0
- package/src/index.ts +1 -1
- package/src/migrateHygraphCli.ts +113 -0
- package/src/migrationActionFactory.ts +230 -0
- package/src/migrations/graphcommerce5to6.ts +4 -6
- package/src/migrations/graphcommerce6to7.ts +4 -6
- package/src/migrations/graphcommerce7to8.ts +4 -6
- package/src/migrations/graphcommerce8to9.ts +79 -8
- package/src/readSchema.ts +24 -29
- package/src/types.ts +6 -1
- package/src/utils/getConfig.ts +33 -0
- package/src/utils/getEndpointUrl.ts +65 -0
- package/src/utils/getManagementClient.ts +15 -0
- package/src/{log-functions.ts → utils/graphCommerceLog.ts} +1 -1
- package/dist/client.js +0 -21
- package/dist/migrateHygraph.js +0 -95
- package/dist/migrationAction.js +0 -133
- package/src/client.ts +0 -25
- package/src/migrateHygraph.ts +0 -86
- package/src/migrationAction.ts +0 -223
|
@@ -2,23 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.graphcommerce7to8 = void 0;
|
|
4
4
|
const management_sdk_1 = require("@hygraph/management-sdk");
|
|
5
|
-
const
|
|
6
|
-
const graphcommerce7to8 = async (schema) => {
|
|
7
|
-
|
|
8
|
-
return 0;
|
|
9
|
-
}
|
|
5
|
+
const migrationActionFactory_1 = require("../migrationActionFactory");
|
|
6
|
+
const graphcommerce7to8 = async (schema, client) => {
|
|
7
|
+
const { migrationAction } = (0, migrationActionFactory_1.migrationActionFactory)(schema, client);
|
|
10
8
|
const hasRow = schema.models
|
|
11
9
|
.find((m) => m.apiId === 'DynamicRow')
|
|
12
10
|
?.fields.some((f) => f.apiId === 'row');
|
|
13
11
|
if (hasRow) {
|
|
14
|
-
|
|
12
|
+
migrationAction(schema, 'unionField', 'update', {
|
|
15
13
|
apiId: 'row',
|
|
16
14
|
displayName: 'Row Deprecated',
|
|
17
15
|
parentApiId: 'DynamicRow',
|
|
18
16
|
description: 'This field is deprecated. Use Rows instead.',
|
|
19
17
|
});
|
|
20
18
|
}
|
|
21
|
-
|
|
19
|
+
migrationAction(schema, 'unionField', 'create', {
|
|
22
20
|
displayName: 'Rows',
|
|
23
21
|
apiId: 'rows',
|
|
24
22
|
isList: true,
|
|
@@ -31,13 +29,13 @@ const graphcommerce7to8 = async (schema) => {
|
|
|
31
29
|
},
|
|
32
30
|
parentApiId: 'DynamicRow',
|
|
33
31
|
}, 'DynamicRow', 'model');
|
|
34
|
-
|
|
32
|
+
migrationAction(schema, 'componentUnionField', 'create', {
|
|
35
33
|
displayName: 'Conditions',
|
|
36
34
|
apiId: 'conditions',
|
|
37
35
|
parentApiId: 'ConditionOr',
|
|
38
36
|
componentApiIds: ['ConditionText', 'ConditionNumber'],
|
|
39
37
|
isList: true,
|
|
40
38
|
}, 'ConditionOr', 'component');
|
|
41
|
-
return
|
|
39
|
+
return client.run(true);
|
|
42
40
|
};
|
|
43
41
|
exports.graphcommerce7to8 = graphcommerce7to8;
|
|
@@ -1,22 +1,68 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.graphcommerce8to9 = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
// This migration is for GC 8.0 and is not yet exported as a usable migration.
|
|
4
|
+
const management_sdk_1 = require("@hygraph/management-sdk");
|
|
5
|
+
const migrationActionFactory_1 = require("../migrationActionFactory");
|
|
6
|
+
const graphcommerce8to9 = async (schema, client) => {
|
|
7
|
+
const { migrationAction } = (0, migrationActionFactory_1.migrationActionFactory)(schema, client);
|
|
10
8
|
// Removes the deprecated 'Row' field which was deprecated in GC@7.1
|
|
11
9
|
const hasRow = schema.models
|
|
12
10
|
.find((m) => m.apiId === 'DynamicRow')
|
|
13
11
|
?.fields.some((f) => f.apiId === 'row');
|
|
14
12
|
if (hasRow) {
|
|
15
|
-
|
|
13
|
+
migrationAction(schema, 'simpleField', 'delete', {
|
|
16
14
|
apiId: 'row',
|
|
17
15
|
parentApiId: 'DynamicRow',
|
|
18
16
|
});
|
|
19
17
|
}
|
|
20
|
-
|
|
18
|
+
const hasRowCategory = schema.models.some((m) => m.apiId === 'RowCategory');
|
|
19
|
+
//
|
|
20
|
+
if (!hasRowCategory) {
|
|
21
|
+
migrationAction(schema, 'model', 'create', {
|
|
22
|
+
apiId: 'RowCategory',
|
|
23
|
+
displayName: 'Row Category',
|
|
24
|
+
apiIdPlural: 'RowProductLists',
|
|
25
|
+
description: 'A model that displays a category',
|
|
26
|
+
});
|
|
27
|
+
migrationAction(schema, 'simpleField', 'create', {
|
|
28
|
+
position: 1,
|
|
29
|
+
type: management_sdk_1.SimpleFieldType.String,
|
|
30
|
+
formConfig: { renderer: 'GCMS_SLUG', config: { isLowercase: true } },
|
|
31
|
+
validations: {
|
|
32
|
+
String: {
|
|
33
|
+
matches: {
|
|
34
|
+
regex: '^[a-z0-9]+(?:[-/][a-z0-9]+)*$',
|
|
35
|
+
errorMessage: 'The category URL must be a valid slug',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
parentApiId: 'RowCategory',
|
|
40
|
+
displayName: 'Category URL',
|
|
41
|
+
apiId: 'categoryUrl',
|
|
42
|
+
description: 'The URL of the category, may include slashes',
|
|
43
|
+
isTitle: true,
|
|
44
|
+
isLocalized: true,
|
|
45
|
+
isRequired: true,
|
|
46
|
+
visibility: management_sdk_1.VisibilityTypes.ReadWrite,
|
|
47
|
+
}, 'RowCategory', 'model');
|
|
48
|
+
migrationAction(schema, 'enumeration', 'create', {
|
|
49
|
+
displayName: 'Row Category Variant',
|
|
50
|
+
apiId: 'RowCategoryVariant',
|
|
51
|
+
values: [
|
|
52
|
+
{ displayName: 'Backstory', apiId: 'Backstory' },
|
|
53
|
+
{ displayName: 'Grid', apiId: 'Grid' },
|
|
54
|
+
{ displayName: 'Swipeable', apiId: 'Swipeable' },
|
|
55
|
+
],
|
|
56
|
+
});
|
|
57
|
+
migrationAction(schema, 'enumerableField', 'create', {
|
|
58
|
+
displayName: 'Variant',
|
|
59
|
+
apiId: 'variant',
|
|
60
|
+
parentApiId: 'RowCategory',
|
|
61
|
+
enumerationApiId: 'RowCategoryVariant',
|
|
62
|
+
description: 'As what variant wil the RowCategory be displayed',
|
|
63
|
+
isRequired: true,
|
|
64
|
+
}, 'RowCategory', 'model');
|
|
65
|
+
}
|
|
66
|
+
return client.run(true);
|
|
21
67
|
};
|
|
22
68
|
exports.graphcommerce8to9 = graphcommerce8to9;
|
package/dist/readSchema.js
CHANGED
|
@@ -2,33 +2,22 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.readSchema = void 0;
|
|
4
4
|
const client_1 = require("@apollo/client");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
if (!config.hygraphProjectId) {
|
|
8
|
-
throw new Error('Please provide GC_HYGRAPH_PROJECT_ID in your env file.');
|
|
9
|
-
}
|
|
10
|
-
if (!config.hygraphWriteAccessToken) {
|
|
11
|
-
throw new Error('Please provide GC_HYGRAPH_WRITE_ACCESS_TOKEN in your env file.');
|
|
12
|
-
}
|
|
13
|
-
const projectId = config.hygraphProjectId;
|
|
14
|
-
if (!config.hygraphManagementApi) {
|
|
15
|
-
throw new Error('Please provide GC_HYGRAPH_MANAGEMENT_API in your env file.');
|
|
16
|
-
}
|
|
17
|
-
const hygraphClient = new client_1.ApolloClient({
|
|
18
|
-
link: new client_1.HttpLink({
|
|
19
|
-
uri: config.hygraphManagementApi,
|
|
20
|
-
fetch: fetch_1.fetch,
|
|
21
|
-
headers: { Authorization: `Bearer ${config.hygraphWriteAccessToken}` },
|
|
22
|
-
}),
|
|
23
|
-
cache: new client_1.InMemoryCache(),
|
|
24
|
-
});
|
|
25
|
-
const { data } = await hygraphClient.query({
|
|
5
|
+
const readSchema = async (managementClient, projectId) => {
|
|
6
|
+
const { data } = await managementClient.query({
|
|
26
7
|
query: (0, client_1.gql) `
|
|
27
8
|
query getSchema($projectId: ID!) {
|
|
28
9
|
viewer {
|
|
29
10
|
project(id: $projectId) {
|
|
30
11
|
environment(name: "master") {
|
|
31
12
|
contentModel {
|
|
13
|
+
locales {
|
|
14
|
+
id
|
|
15
|
+
apiId
|
|
16
|
+
}
|
|
17
|
+
stages {
|
|
18
|
+
id
|
|
19
|
+
apiId
|
|
20
|
+
}
|
|
32
21
|
models {
|
|
33
22
|
apiId
|
|
34
23
|
apiIdPlural
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getConfig = getConfig;
|
|
4
|
+
function getConfig(config) {
|
|
5
|
+
let { hygraphProjectId: projectId, hygraphWriteAccessToken: authToken, hygraphManagementApi: uri, hygraphEndpoint, } = config;
|
|
6
|
+
if (!authToken) {
|
|
7
|
+
throw new Error('Please provide GC_HYGRAPH_WRITE_ACCESS_TOKEN in your env file.');
|
|
8
|
+
}
|
|
9
|
+
if (!projectId) {
|
|
10
|
+
projectId = new URL(hygraphEndpoint).pathname.split('/')?.[1];
|
|
11
|
+
}
|
|
12
|
+
if (!uri) {
|
|
13
|
+
const endpoint = new URL(hygraphEndpoint);
|
|
14
|
+
endpoint.hostname = `management-${endpoint.hostname}`.replace('.cdn', '');
|
|
15
|
+
endpoint.pathname = 'graphql';
|
|
16
|
+
uri = endpoint.toString();
|
|
17
|
+
}
|
|
18
|
+
return { projectId, authToken, uri };
|
|
19
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getEnvironment = getEnvironment;
|
|
7
|
+
const graphql_tag_1 = __importDefault(require("graphql-tag"));
|
|
8
|
+
async function getEnvironment(client, config) {
|
|
9
|
+
const endpoints = await client.query({
|
|
10
|
+
query: (0, graphql_tag_1.default) `
|
|
11
|
+
query Environments($projectId: ID!) {
|
|
12
|
+
viewer {
|
|
13
|
+
id
|
|
14
|
+
project(id: $projectId) {
|
|
15
|
+
environments {
|
|
16
|
+
name
|
|
17
|
+
endpoint
|
|
18
|
+
migrations {
|
|
19
|
+
name
|
|
20
|
+
status
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
`,
|
|
27
|
+
variables: { projectId: config.projectId },
|
|
28
|
+
errorPolicy: 'all',
|
|
29
|
+
});
|
|
30
|
+
if (endpoints.errors) {
|
|
31
|
+
const isBadInput = endpoints.errors.some((e) => e.extensions?.code === 'BAD_USER_INPUT');
|
|
32
|
+
if (isBadInput) {
|
|
33
|
+
throw Error(`
|
|
34
|
+
Could not find environment for projectId ${config.projectId}.
|
|
35
|
+
Please check your GC_HYGRAPH_PROJECT_ID in your env file.
|
|
36
|
+
`);
|
|
37
|
+
}
|
|
38
|
+
throw new Error(`An error occurred: ${endpoints.errors.map((e) => e.message).join('\n')}`);
|
|
39
|
+
}
|
|
40
|
+
const environment = endpoints.data.viewer.project.environments.find((env) => env.name === 'master') ??
|
|
41
|
+
endpoints.data.viewer.project.environments?.[0];
|
|
42
|
+
return environment;
|
|
43
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getManagementClient = getManagementClient;
|
|
4
|
+
const client_1 = require("@apollo/client");
|
|
5
|
+
function getManagementClient(config) {
|
|
6
|
+
const { authToken: accessToken, uri } = config;
|
|
7
|
+
return new client_1.ApolloClient({
|
|
8
|
+
link: new client_1.HttpLink({
|
|
9
|
+
uri,
|
|
10
|
+
fetch,
|
|
11
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
12
|
+
}),
|
|
13
|
+
cache: new client_1.InMemoryCache(),
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -10,6 +10,6 @@ const graphcommerceLog = (message, type) => {
|
|
|
10
10
|
info: '\x1b[36m\x1b[1m%s\x1b[0m',
|
|
11
11
|
};
|
|
12
12
|
// eslint-disable-next-line no-console
|
|
13
|
-
console.log(type ? color[type] : '',
|
|
13
|
+
console.log(type ? color[type] : '', `${message}`);
|
|
14
14
|
};
|
|
15
15
|
exports.graphcommerceLog = graphcommerceLog;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@graphcommerce/hygraph-cli",
|
|
3
3
|
"homepage": "https://www.graphcommerce.org/",
|
|
4
4
|
"repository": "github:graphcommerce-org/graphcommerce",
|
|
5
|
-
"version": "9.0.0-canary.
|
|
5
|
+
"version": "9.0.0-canary.74",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "tsc --preserveWatchOutput --watch",
|
|
8
8
|
"build": "tsc",
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"@apollo/client": "^3",
|
|
22
|
-
"@graphcommerce/eslint-config-pwa": "^9.0.0-canary.
|
|
23
|
-
"@graphcommerce/next-config": "^9.0.0-canary.
|
|
24
|
-
"@graphcommerce/prettier-config-pwa": "^9.0.0-canary.
|
|
25
|
-
"@graphcommerce/typescript-config-pwa": "^9.0.0-canary.
|
|
22
|
+
"@graphcommerce/eslint-config-pwa": "^9.0.0-canary.74",
|
|
23
|
+
"@graphcommerce/next-config": "^9.0.0-canary.74",
|
|
24
|
+
"@graphcommerce/prettier-config-pwa": "^9.0.0-canary.74",
|
|
25
|
+
"@graphcommerce/typescript-config-pwa": "^9.0.0-canary.74",
|
|
26
26
|
"dotenv": "^16.1.4",
|
|
27
27
|
"graphql": "^16.7.1"
|
|
28
28
|
},
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BatchMigrationCreateComponentFieldInput,
|
|
3
|
+
BatchMigrationCreateComponentInput,
|
|
4
|
+
BatchMigrationCreateComponentUnionFieldInput,
|
|
5
|
+
BatchMigrationCreateEnumerableFieldInput,
|
|
6
|
+
BatchMigrationCreateEnumerationInput,
|
|
7
|
+
BatchMigrationCreateLocaleInput,
|
|
8
|
+
BatchMigrationCreateModelInput,
|
|
9
|
+
BatchMigrationCreateRelationalFieldInput,
|
|
10
|
+
BatchMigrationCreateSimpleFieldInput,
|
|
11
|
+
BatchMigrationCreateStageInput,
|
|
12
|
+
BatchMigrationCreateUnionFieldInput,
|
|
13
|
+
Client,
|
|
14
|
+
} from '@hygraph/management-sdk'
|
|
15
|
+
import { Schema } from './types'
|
|
16
|
+
|
|
17
|
+
interface MigrationParams {
|
|
18
|
+
name?: string
|
|
19
|
+
endpoint: string
|
|
20
|
+
authToken: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class UpsertClient extends Client {
|
|
24
|
+
constructor(
|
|
25
|
+
params: MigrationParams,
|
|
26
|
+
private schema: Schema,
|
|
27
|
+
) {
|
|
28
|
+
super(params)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
upsertModel(data: BatchMigrationCreateModelInput) {
|
|
32
|
+
const exists = this.schema.models.some((m) => m.apiId === data.apiId)
|
|
33
|
+
return exists ? this.createModel(data) : this.updateModel(data)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
upsertComponent(data: BatchMigrationCreateComponentInput) {
|
|
37
|
+
const exists = this.schema.models.some((m) => m.apiId === data.apiId)
|
|
38
|
+
return exists ? this.createComponent(data) : this.updateComponent(data)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
upsertSimpleField(data: BatchMigrationCreateSimpleFieldInput) {
|
|
42
|
+
const model = this.schema.models.find((m) => m.apiId === data.parentApiId)
|
|
43
|
+
const exists = model?.fields.some((f) => f.apiId === data.apiId)
|
|
44
|
+
return exists
|
|
45
|
+
? this.createSimpleField(data)
|
|
46
|
+
: this.updateSimpleField({ ...data, embeddableModels: undefined })
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// upsertRemoteField(data: BatchMigrationCreateRemoteFieldInput) {
|
|
50
|
+
// const model = this.schema.models.find((m) => m.apiId === data.parentApiId)
|
|
51
|
+
// const exists = model?.fields.some((f) => f.apiId === data.apiId)
|
|
52
|
+
// return exists ? this.createRemoteField(data) : this.updateRemoteField(data)
|
|
53
|
+
// }
|
|
54
|
+
|
|
55
|
+
upsertRelationalField(data: BatchMigrationCreateRelationalFieldInput) {
|
|
56
|
+
const model = this.schema.models.find((m) => m.apiId === data.parentApiId)
|
|
57
|
+
const exists = model?.fields.some((f) => f.apiId === data.apiId)
|
|
58
|
+
return exists ? this.createRelationalField(data) : this.updateRelationalField(data)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
upsertUnionField(data: BatchMigrationCreateUnionFieldInput) {
|
|
62
|
+
const model = this.schema.models.find((m) => m.apiId === data.parentApiId)
|
|
63
|
+
const exists = model?.fields.some((f) => f.apiId === data.apiId)
|
|
64
|
+
return exists ? this.createUnionField(data) : this.updateUnionField(data)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
upsertComponentField(data: BatchMigrationCreateComponentFieldInput) {
|
|
68
|
+
const model = this.schema.models.find((m) => m.apiId === data.parentApiId)
|
|
69
|
+
const exists = model?.fields.some((f) => f.apiId === data.apiId)
|
|
70
|
+
return exists ? this.createComponentField(data) : this.updateComponentField(data)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
upsertComponentUnionField(data: BatchMigrationCreateComponentUnionFieldInput) {
|
|
74
|
+
const model = this.schema.models.find((m) => m.apiId === data.parentApiId)
|
|
75
|
+
const exists = model?.fields.some((f) => f.apiId === data.apiId)
|
|
76
|
+
return exists ? this.createComponentUnionField(data) : this.updateComponentUnionField(data)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
upsertEnumeration(data: BatchMigrationCreateEnumerationInput) {
|
|
80
|
+
const exists = this.schema.enumerations.some((e) => e.apiId === data.apiId)
|
|
81
|
+
return exists ? this.createEnumeration(data) : this.updateEnumeration(data)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
upsertEnumerableField(data: BatchMigrationCreateEnumerableFieldInput) {
|
|
85
|
+
const model = this.schema.models.find((m) => m.apiId === data.parentApiId)
|
|
86
|
+
const exists = model?.fields.some((f) => f.apiId === data.apiId)
|
|
87
|
+
return exists ? this.createEnumerableField(data) : this.updateEnumerableField(data)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
upsertStage(data: BatchMigrationCreateStageInput) {
|
|
91
|
+
const exists = this.schema.stages.some((m) => m.apiId === data.apiId)
|
|
92
|
+
return exists ? this.createStage(data) : this.updateStage(data)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
upsertLocale(data: BatchMigrationCreateLocaleInput) {
|
|
96
|
+
const exists = this.schema.locales.some((m) => m.apiId === data.apiId)
|
|
97
|
+
return exists ? this.createLocale(data) : this.updateLocale(data)
|
|
98
|
+
}
|
|
99
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { migrateHygraph } from './
|
|
1
|
+
export { migrateHygraphCli as migrateHygraph } from './migrateHygraphCli'
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import { loadConfig } from '@graphcommerce/next-config'
|
|
3
|
+
import dotenv from 'dotenv'
|
|
4
|
+
import prompts, { PromptObject } from 'prompts'
|
|
5
|
+
import { UpsertClient } from './UpsertClient'
|
|
6
|
+
import * as availableMigrations from './migrations'
|
|
7
|
+
import { readSchema } from './readSchema'
|
|
8
|
+
import { MigrationFunction, Schema } from './types'
|
|
9
|
+
import { getConfig } from './utils/getConfig'
|
|
10
|
+
import { getEnvironment } from './utils/getEndpointUrl'
|
|
11
|
+
import { getManagementClient } from './utils/getManagementClient'
|
|
12
|
+
import { graphcommerceLog } from './utils/graphCommerceLog'
|
|
13
|
+
|
|
14
|
+
dotenv.config()
|
|
15
|
+
|
|
16
|
+
export async function migrateHygraphCli() {
|
|
17
|
+
const hygraphConfig = getConfig(loadConfig(process.cwd()))
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Extracting the current GC version. Are we gonna use the current version to determine which
|
|
21
|
+
* scripts should be runned? Or do we let the user pick the migration from a list? 🤔
|
|
22
|
+
*/
|
|
23
|
+
const packageJson = fs.readFileSync('package.json', 'utf8')
|
|
24
|
+
const packageData = JSON.parse(packageJson)
|
|
25
|
+
const graphcommerceVersion = packageData.dependencies['@graphcommerce/next-ui']
|
|
26
|
+
graphcommerceLog(`Graphcommerce version: ${graphcommerceVersion}`, 'info')
|
|
27
|
+
|
|
28
|
+
const mangementClient = getManagementClient(hygraphConfig)
|
|
29
|
+
// Extract the currently existing models, components and enumerations from the Hygraph schema.
|
|
30
|
+
const schemaViewer = await readSchema(mangementClient, hygraphConfig.projectId)
|
|
31
|
+
const schema: Schema = schemaViewer.viewer.project.environment.contentModel
|
|
32
|
+
|
|
33
|
+
// A list of possible migrations
|
|
34
|
+
const possibleMigrations: [string, MigrationFunction][] = Object.entries(availableMigrations)
|
|
35
|
+
|
|
36
|
+
// Here we setup the list we ask the user to choose from
|
|
37
|
+
const selectMigrationInput: PromptObject<string> = {
|
|
38
|
+
type: 'select',
|
|
39
|
+
name: 'selectedMigration',
|
|
40
|
+
message: '\x1b[36m\x1b[1m[]: Select migration',
|
|
41
|
+
choices: possibleMigrations.map(([name, migration]) => ({
|
|
42
|
+
title: name,
|
|
43
|
+
value: { name, migration },
|
|
44
|
+
})),
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Here we ask the user to choose a migration from a list of possible migrations
|
|
48
|
+
try {
|
|
49
|
+
graphcommerceLog('Available migrations: ', 'info')
|
|
50
|
+
const selectMigrationOutput = await prompts(selectMigrationInput)
|
|
51
|
+
|
|
52
|
+
let { migration, name } = selectMigrationOutput.selectedMigration as {
|
|
53
|
+
name: string
|
|
54
|
+
migration: MigrationFunction
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
graphcommerceLog(
|
|
58
|
+
`You have selected the ${selectMigrationOutput.selectedMigration.name} migration`,
|
|
59
|
+
'info',
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const { endpoint, migrations } = await getEnvironment(mangementClient, hygraphConfig)
|
|
64
|
+
|
|
65
|
+
const migrationExists = migrations.find(
|
|
66
|
+
(m) => m.name?.startsWith(name) && m.status === 'SUCCESS',
|
|
67
|
+
)
|
|
68
|
+
if (migrationExists) {
|
|
69
|
+
if (!process.argv.includes('--force')) {
|
|
70
|
+
graphcommerceLog(
|
|
71
|
+
`Migration ${name} as ${migrationExists.name} already exists in Hygraph with the status SUCCESS. To rerun this migration use the --force option. Exiting now..`,
|
|
72
|
+
'info',
|
|
73
|
+
)
|
|
74
|
+
process.exit(1)
|
|
75
|
+
} else {
|
|
76
|
+
graphcommerceLog(
|
|
77
|
+
`Migration ${name} as ${migrationExists.name} already exists in Hygraph with the status SUCCESS. Using --force, rerunning migration..`,
|
|
78
|
+
'warning',
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
name = `${name}-${Date.now()}`
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Here we try to run the migration
|
|
85
|
+
const result = await migration(
|
|
86
|
+
schema,
|
|
87
|
+
new UpsertClient({ authToken: hygraphConfig.authToken, endpoint, name }, schema),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
graphcommerceLog(`Migration result: ${JSON.stringify(result)}`, 'info')
|
|
91
|
+
if (!result) {
|
|
92
|
+
graphcommerceLog(
|
|
93
|
+
'No migration client found. Please make sure your GC_HYGRAPH_WRITE_ACCESS_TOKEN in your env file is correct.',
|
|
94
|
+
)
|
|
95
|
+
process.exit(1)
|
|
96
|
+
}
|
|
97
|
+
if (result.status !== 'SUCCESS') {
|
|
98
|
+
graphcommerceLog(`Migration not successful: ${result.status} ${name}:\n${result.errors}`)
|
|
99
|
+
process.exit(1)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
graphcommerceLog(`Migration successful: ${name}`, 'info')
|
|
103
|
+
} catch (err) {
|
|
104
|
+
if (err instanceof Error) {
|
|
105
|
+
const garbledErrorIndex = err.message.indexOf(': {"')
|
|
106
|
+
const msg = garbledErrorIndex > 0 ? err.message.slice(0, garbledErrorIndex) : err.message
|
|
107
|
+
graphcommerceLog(`${msg}`, 'error')
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
} catch (error) {
|
|
111
|
+
graphcommerceLog(`An error occurred: ${error}`, 'error')
|
|
112
|
+
}
|
|
113
|
+
}
|