@graphcommerce/hygraph-cli 7.0.0-canary.21 → 7.0.0

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.
@@ -1,28 +1,22 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.dynamicRow = void 0;
7
- const next_config_1 = require("@graphcommerce/next-config");
3
+ exports.graphcommerce6to7 = void 0;
8
4
  const management_sdk_1 = require("@hygraph/management-sdk");
9
- const dotenv_1 = __importDefault(require("dotenv"));
10
- dotenv_1.default.config();
11
- const dynamicRow = async (name) => {
12
- const config = (0, next_config_1.loadConfig)(process.cwd());
13
- if (!config.hygraphWriteAccessEndpoint) {
14
- throw new Error('Please provide hygraphWriteAccessEndpoint in your config or GC_HYGRAPH_WRITE_ACCESS_ENDPOINT in your env');
15
- }
16
- if (!config.hygraphWriteAccessToken) {
17
- throw new Error('Please provide GC_HYGRAPH_WRITE_ACCESS_TOKEN in your env');
5
+ const migrationAction_1 = require("../migrationAction");
6
+ const graphcommerce6to7 = async (schema) => {
7
+ if (!migrationAction_1.client) {
8
+ return 0;
18
9
  }
19
- const client = new management_sdk_1.Client({
20
- authToken: config.hygraphWriteAccessToken,
21
- endpoint: config.hygraphWriteAccessEndpoint,
22
- name,
23
- });
24
10
  // ? ENUMERATIONS
25
- client.createEnumeration({
11
+ (0, migrationAction_1.migrationAction)(schema, 'enumeration', 'create', {
12
+ displayName: 'Row Column One Variants',
13
+ apiId: 'RowColumnOneVariants',
14
+ values: [
15
+ { displayName: 'Default', apiId: 'Default' },
16
+ { displayName: 'Message', apiId: 'Message' },
17
+ ],
18
+ });
19
+ (0, migrationAction_1.migrationAction)(schema, 'enumeration', 'create', {
26
20
  displayName: 'Dynamic Row Condition Number Operator',
27
21
  apiId: 'DynamicRowConditionNumberOperator',
28
22
  values: [
@@ -31,7 +25,7 @@ const dynamicRow = async (name) => {
31
25
  { displayName: 'Equal to', apiId: 'EQUAL' },
32
26
  ],
33
27
  });
34
- client.createEnumeration({
28
+ (0, migrationAction_1.migrationAction)(schema, 'enumeration', 'create', {
35
29
  displayName: 'Dynamic Row Placement',
36
30
  apiId: 'DynamicRowPlacement',
37
31
  values: [
@@ -41,43 +35,36 @@ const dynamicRow = async (name) => {
41
35
  ],
42
36
  });
43
37
  // ? COMPONENTS
44
- client.createComponent({
38
+ (0, migrationAction_1.migrationAction)(schema, 'component', 'create', {
45
39
  displayName: 'Text',
46
40
  apiId: 'ConditionText',
47
41
  apiIdPlural: 'ConditionTexts',
48
42
  });
49
- client.createComponent({
43
+ (0, migrationAction_1.migrationAction)(schema, 'component', 'create', {
50
44
  displayName: 'Number',
51
45
  apiId: 'ConditionNumber',
52
46
  apiIdPlural: 'ConditionNumbers',
53
47
  });
54
- client.createComponent({
48
+ (0, migrationAction_1.migrationAction)(schema, 'component', 'create', {
55
49
  displayName: 'AND',
56
50
  apiId: 'ConditionAnd',
57
51
  apiIdPlural: 'ConditionAnds',
58
52
  description: 'All of these conditions must match',
59
53
  });
60
- client.createComponent({
54
+ (0, migrationAction_1.migrationAction)(schema, 'component', 'create', {
61
55
  displayName: 'OR',
62
56
  apiId: 'ConditionOr',
63
57
  apiIdPlural: 'ConditionOrs',
64
58
  description: 'One of these conditions must match',
65
59
  });
66
- client.createComponentUnionField({
60
+ (0, migrationAction_1.migrationAction)(schema, 'componentUnionField', 'create', {
67
61
  displayName: 'Conditions',
68
62
  apiId: 'conditions',
69
63
  parentApiId: 'ConditionAnd',
70
64
  componentApiIds: ['ConditionOr', 'ConditionText', 'ConditionNumber'],
71
65
  isList: true,
72
- });
73
- client.createComponentUnionField({
74
- displayName: 'Conditions',
75
- apiId: 'conditions',
76
- parentApiId: 'ConditionOr',
77
- componentApiIds: ['ConditionText', 'ConditionNumber'],
78
- isList: true,
79
- });
80
- client.createSimpleField({
66
+ }, 'ConditionAnd', 'component');
67
+ (0, migrationAction_1.migrationAction)(schema, 'simpleField', 'create', {
81
68
  displayName: 'Property',
82
69
  apiId: 'property',
83
70
  type: management_sdk_1.SimpleFieldType.String,
@@ -93,15 +80,15 @@ const dynamicRow = async (name) => {
93
80
  },
94
81
  },
95
82
  },
96
- });
97
- client.createSimpleField({
83
+ }, 'ConditionText', 'component');
84
+ (0, migrationAction_1.migrationAction)(schema, 'simpleField', 'create', {
98
85
  displayName: 'Value',
99
86
  apiId: 'value',
100
87
  type: management_sdk_1.SimpleFieldType.String,
101
88
  parentApiId: 'ConditionText',
102
89
  isRequired: true,
103
- });
104
- client.createSimpleField({
90
+ }, 'ConditionText', 'component');
91
+ (0, migrationAction_1.migrationAction)(schema, 'simpleField', 'create', {
105
92
  displayName: 'Property',
106
93
  apiId: 'property',
107
94
  type: management_sdk_1.SimpleFieldType.String,
@@ -116,29 +103,29 @@ const dynamicRow = async (name) => {
116
103
  },
117
104
  },
118
105
  },
119
- });
120
- client.createEnumerableField({
106
+ }, 'ConditionNumber', 'component');
107
+ (0, migrationAction_1.migrationAction)(schema, 'enumerableField', 'create', {
121
108
  displayName: 'Operator',
122
109
  apiId: 'operator',
123
110
  parentApiId: 'ConditionNumber',
124
111
  enumerationApiId: 'DynamicRowConditionNumberOperator',
125
112
  isRequired: true,
126
- });
127
- client.createSimpleField({
113
+ }, 'ConditionNumber', 'component');
114
+ (0, migrationAction_1.migrationAction)(schema, 'simpleField', 'create', {
128
115
  displayName: 'Value',
129
116
  apiId: 'value',
130
117
  type: management_sdk_1.SimpleFieldType.Float,
131
118
  parentApiId: 'ConditionNumber',
132
119
  isRequired: true,
133
- });
120
+ }, 'ConditionNumber', 'component');
134
121
  // ? MODEL
135
- client.createModel({
122
+ (0, migrationAction_1.migrationAction)(schema, 'model', 'create', {
123
+ displayName: 'Dynamic Row',
136
124
  apiId: 'DynamicRow',
137
125
  apiIdPlural: 'DynamicRows',
138
- displayName: 'Dynamic Row',
139
126
  description: 'Dynamic rows allow you to add specific Row models to pages based on the properties of the page',
140
127
  });
141
- client.createSimpleField({
128
+ (0, migrationAction_1.migrationAction)(schema, 'simpleField', 'create', {
142
129
  displayName: 'Internal name',
143
130
  apiId: 'internalName',
144
131
  description: 'Only used for internal reference',
@@ -147,8 +134,8 @@ const dynamicRow = async (name) => {
147
134
  isRequired: true,
148
135
  isUnique: true,
149
136
  modelApiId: 'DynamicRow',
150
- });
151
- client.createUnionField({
137
+ }, 'DynamicRow', 'model');
138
+ (0, migrationAction_1.migrationAction)(schema, 'unionField', 'create', {
152
139
  displayName: 'Row',
153
140
  apiId: 'row',
154
141
  reverseField: {
@@ -159,16 +146,16 @@ const dynamicRow = async (name) => {
159
146
  isList: true,
160
147
  },
161
148
  parentApiId: 'DynamicRow',
162
- });
163
- client.createEnumerableField({
149
+ }, 'DynamicRow', 'model');
150
+ (0, migrationAction_1.migrationAction)(schema, 'enumerableField', 'create', {
164
151
  displayName: 'Placement',
165
152
  apiId: 'placement',
166
153
  parentApiId: 'DynamicRow',
167
154
  enumerationApiId: 'DynamicRowPlacement',
168
155
  description: 'Where will the row be placed relative to the target',
169
156
  isRequired: true,
170
- });
171
- client.createUnionField({
157
+ }, 'DynamicRow', 'model');
158
+ (0, migrationAction_1.migrationAction)(schema, 'unionField', 'create', {
172
159
  displayName: 'Placement target',
173
160
  apiId: 'target',
174
161
  description: 'Optional: When the target is left blank it will place the Dynamic Row on the start or end.',
@@ -193,15 +180,22 @@ const dynamicRow = async (name) => {
193
180
  isList: true,
194
181
  },
195
182
  parentApiId: 'DynamicRow',
196
- });
197
- client.createComponentUnionField({
183
+ }, 'DynamicRow', 'model');
184
+ (0, migrationAction_1.migrationAction)(schema, 'componentUnionField', 'create', {
198
185
  displayName: 'Conditions (OR)',
199
186
  apiId: 'conditions',
200
187
  parentApiId: 'DynamicRow',
201
188
  description: 'One of these conditions must match',
202
189
  componentApiIds: ['ConditionAnd', 'ConditionText', 'ConditionNumber'],
203
190
  isList: true,
204
- });
205
- return client.run(true);
191
+ }, 'DynamicRow', 'model');
192
+ // ? Row Column One
193
+ (0, migrationAction_1.migrationAction)(schema, 'enumerableField', 'create', {
194
+ displayName: 'Variant',
195
+ apiId: 'rowColumnOneVariant',
196
+ enumerationApiId: 'RowColumnOneVariants',
197
+ parentApiId: 'RowColumnOne',
198
+ }, 'RowColumnOne', 'model');
199
+ return migrationAction_1.client.run(true);
206
200
  };
207
- exports.dynamicRow = dynamicRow;
201
+ exports.graphcommerce6to7 = graphcommerce6to7;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./graphcommerce5to6"), exports);
18
+ __exportStar(require("./graphcommerce6to7"), exports);
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readSchema = void 0;
4
+ const client_1 = require("@apollo/client");
5
+ const fetch_1 = require("@whatwg-node/fetch");
6
+ const readSchema = async (config) => {
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
+ const hygraphClient = new client_1.ApolloClient({
15
+ link: new client_1.HttpLink({
16
+ uri: 'https://management.hygraph.com/graphql',
17
+ fetch: fetch_1.fetch,
18
+ headers: { Authorization: `Bearer ${config.hygraphWriteAccessToken}` },
19
+ }),
20
+ cache: new client_1.InMemoryCache(),
21
+ });
22
+ const { data } = await hygraphClient.query({
23
+ query: (0, client_1.gql) `
24
+ query getSchema($projectId: ID!) {
25
+ viewer {
26
+ project(id: $projectId) {
27
+ environment(name: "master") {
28
+ contentModel {
29
+ models {
30
+ apiId
31
+ apiIdPlural
32
+ fields {
33
+ apiId
34
+ }
35
+ }
36
+ components {
37
+ apiId
38
+ apiIdPlural
39
+ fields {
40
+ apiId
41
+ }
42
+ }
43
+ enumerations {
44
+ apiId
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }
50
+ }
51
+ `,
52
+ variables: {
53
+ projectId,
54
+ },
55
+ });
56
+ return data;
57
+ };
58
+ exports.readSchema = readSchema;
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": "7.0.0-canary.21",
5
+ "version": "7.0.0",
6
6
  "author": "",
7
7
  "license": "MIT",
8
8
  "scripts": {
@@ -14,20 +14,23 @@
14
14
  "main": "dist/index.js",
15
15
  "types": "src/index.ts",
16
16
  "dependencies": {
17
- "@graphcommerce/next-config": "7.0.0-canary.21",
18
- "@graphql-codegen/cli": "3.2.2",
19
- "@graphql-mesh/cli": "latest",
20
- "@graphql-mesh/types": "latest",
21
- "@graphql-mesh/utils": "latest",
22
- "@hygraph/management-sdk": "^1.1.2-alpha.1",
23
- "graphql": "16.6.0",
24
- "graphql-tag": "^2.12.6"
17
+ "@apollo/client": "~3.7.17",
18
+ "@graphcommerce/next-config": "7.0.0",
19
+ "@hygraph/management-sdk": "1.2.3",
20
+ "graphql-tag": "^2.12.6",
21
+ "prompts": "^2.4.2",
22
+ "@whatwg-node/fetch": "^0.9.4"
23
+ },
24
+ "peerDependencies": {
25
+ "graphql": "^16.7.1",
26
+ "dotenv": "^16.1.4"
25
27
  },
26
28
  "devDependencies": {
27
- "@graphcommerce/eslint-config-pwa": "7.0.0-canary.21",
28
- "@graphcommerce/prettier-config-pwa": "7.0.0-canary.21",
29
- "@graphcommerce/typescript-config-pwa": "7.0.0-canary.21",
30
- "typescript": "4.9.5"
29
+ "@types/prompts": "^2.4.4",
30
+ "@graphcommerce/eslint-config-pwa": "7.0.0",
31
+ "@graphcommerce/prettier-config-pwa": "7.0.0",
32
+ "@graphcommerce/typescript-config-pwa": "7.0.0",
33
+ "typescript": "5.1.3"
31
34
  },
32
35
  "sideEffects": false,
33
36
  "prettier": "@graphcommerce/prettier-config-pwa",
package/src/client.ts ADDED
@@ -0,0 +1,25 @@
1
+ import { GraphCommerceConfig } from '@graphcommerce/next-config'
2
+ import { Client } from '@hygraph/management-sdk'
3
+ import { graphcommerceLog } from './log-functions'
4
+
5
+ export const initClient = (config: GraphCommerceConfig, name: string | undefined) => {
6
+ if (!config.hygraphWriteAccessEndpoint) {
7
+ graphcommerceLog(
8
+ 'Please provide hygraphWriteAccessEndpoint in your config or GC_HYGRAPH_WRITE_ACCESS_ENDPOINT in your env file',
9
+ 'error',
10
+ )
11
+
12
+ return 0
13
+ }
14
+ if (!config.hygraphWriteAccessToken) {
15
+ graphcommerceLog('Please provide GC_HYGRAPH_WRITE_ACCESS_TOKEN in your env file')
16
+
17
+ return 0
18
+ }
19
+
20
+ return new Client({
21
+ authToken: config.hygraphWriteAccessToken,
22
+ endpoint: config.hygraphWriteAccessEndpoint,
23
+ name,
24
+ })
25
+ }
@@ -0,0 +1,12 @@
1
+ export const capitalize = (word: string) =>
2
+ word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
3
+
4
+ export const graphcommerceLog = (message: string, type?: 'info' | 'warning' | 'error') => {
5
+ const color = {
6
+ error: '\x1b[31m\x1b[1m%s\x1b[0m',
7
+ warning: '\x1b[33m\x1b[1m%s\x1b[0m',
8
+ info: '\x1b[36m\x1b[1m%s\x1b[0m',
9
+ }
10
+ // eslint-disable-next-line no-console
11
+ console.log(type ? color[type] : '', `[GraphCommerce]: ${message}`)
12
+ }
@@ -1,73 +1,86 @@
1
- /* eslint-disable no-console */
2
- /* eslint-disable import/no-extraneous-dependencies */
3
- import readline from 'readline'
4
- import { MigrationInfo } from '@hygraph/management-sdk/dist/ManagementAPIClient'
5
- import { dynamicRow } from './migrations/dynamicRow'
1
+ import fs from 'fs'
2
+ import { loadConfig } from '@graphcommerce/next-config'
3
+ import type { MigrationInfo } from '@hygraph/management-sdk/dist/src/ManagementAPIClient'
4
+ import dotenv from 'dotenv'
5
+ import prompts, { PromptObject } from 'prompts'
6
+ import { graphcommerceLog } from './log-functions'
7
+ import * as migrations from './migrations'
8
+ import { readSchema } from './readSchema'
9
+ import { Schema } from './types'
6
10
 
7
- export async function migrateHygraph() {
8
- let forceRun = false
9
-
10
- // Interface to determine if force run should be enabled
11
- readline.createInterface({
12
- input: process.stdin,
13
- output: process.stdout,
14
- })
11
+ dotenv.config()
15
12
 
16
- const affirmativeAnswers = ['y', 'yes', 'Y', 'YES']
13
+ export async function migrateHygraph() {
14
+ const config = loadConfig(process.cwd())
17
15
 
18
- const handleKeypress = (key: string) => {
19
- if (affirmativeAnswers.includes(key.toLowerCase())) {
20
- console.log('\nForce run enabled')
21
- forceRun = true
22
- } else {
23
- console.log('\nForce run disabled')
24
- forceRun = false
25
- }
16
+ /**
17
+ * Extracting the current GC version. Are we gonna use the current version to determine which
18
+ * scripts should be runned? Or do we let the user pick the migration from a list? 🤔
19
+ */
20
+ const packageJson = fs.readFileSync('package.json', 'utf8')
21
+ const packageData = JSON.parse(packageJson)
22
+ const graphcommerceVersion = packageData.dependencies['@graphcommerce/next-ui']
26
23
 
27
- process.stdin.pause()
28
- }
24
+ graphcommerceLog(`Graphcommerce version: ${graphcommerceVersion}`, 'info')
29
25
 
30
- // Listen for keypress events
31
- process.stdin.on('keypress', handleKeypress)
32
- process.stdin.setRawMode(true)
33
- process.stdin.resume()
26
+ // Extract the currently existing models, components and enumerations from the Hygraph schema.
27
+ const schemaViewer = await readSchema(config)
28
+ const schema: Schema = schemaViewer.viewer.project.environment.contentModel
34
29
 
35
- console.log('Enable force run? (y/n)')
30
+ // A list of possible migrations
31
+ const possibleMigrations: [string, (schema: Schema) => Promise<0 | MigrationInfo>][] =
32
+ Object.entries(migrations)
36
33
 
37
- // Wait for input
38
- await new Promise<void>((resolve) => {
39
- process.stdin.once('data', () => {
40
- // Stop listening for input
41
- process.stdin.removeListener('keypress', handleKeypress)
42
- process.stdin.setRawMode(false)
34
+ // Here we setup the list we ask the user to choose from
35
+ const selectMigrationInput: PromptObject<string> | PromptObject<string>[] = {
36
+ type: 'select',
37
+ name: 'selectedMigration',
38
+ message: '\x1b[36m\x1b[1m[GraphCommerce]: Select migration',
39
+ choices: [],
40
+ }
43
41
 
44
- resolve()
45
- })
46
- })
42
+ for (const [name, migration] of possibleMigrations) {
43
+ if (Array.isArray(selectMigrationInput.choices)) {
44
+ selectMigrationInput?.choices?.push({ title: name, value: { name, migration } })
45
+ }
46
+ }
47
47
 
48
- // TODO: Choose migration
49
- // TODO: GC-Version based migration
50
- const possibleMigrations: [string, (name: string | undefined) => Promise<MigrationInfo>][] = [
51
- ['add_dynamic_rows', dynamicRow],
52
- ]
48
+ // Here we ask the user to choose a migration from a list of possible migrations
49
+ try {
50
+ graphcommerceLog('Available migrations: ', 'info')
51
+ const selectMigrationOutput = await prompts(selectMigrationInput)
52
+ const { migration, name } = selectMigrationOutput.selectedMigration
53
+ graphcommerceLog(
54
+ `You have selected the ${selectMigrationOutput.selectedMigration.name} migration`,
55
+ 'info',
56
+ )
53
57
 
54
- for (const [name, migration] of possibleMigrations) {
55
58
  try {
59
+ // Here we try to run the migration
56
60
  // eslint-disable-next-line no-await-in-loop
57
- const result = await migration(forceRun ? undefined : name)
58
- console.log(result)
61
+ const result = await migration(schema)
59
62
 
63
+ graphcommerceLog(`Migration result: ${JSON.stringify(result)}`, 'info')
64
+ if (!result) {
65
+ throw new Error(
66
+ '[GraphCommerce]: No migration client found. Please make sure your GC_HYGRAPH_WRITE_ACCESS_ENDPOINT and GC_HYGRAPH_WRITE_ACCESS_TOKEN in your env file are correct.',
67
+ )
68
+ }
60
69
  if (result.status !== 'SUCCESS') {
61
- throw new Error(`Migration not successful: ${result.status} ${name}:\n${result.errors}`)
70
+ throw new Error(
71
+ `[GraphCommerce]: Migration not successful: ${result.status} ${name}:\n${result.errors}`,
72
+ )
62
73
  }
63
74
 
64
- console.log(`Migration successful: ${name}`)
75
+ graphcommerceLog(`Migration successful: ${name}`, 'info')
65
76
  } catch (err) {
66
77
  if (err instanceof Error) {
67
78
  const garbledErrorIndex = err.message.indexOf(': {"')
68
79
  const msg = garbledErrorIndex > 0 ? err.message.slice(0, garbledErrorIndex) : err.message
69
- console.error(msg)
80
+ graphcommerceLog(`${msg}`, 'error')
70
81
  }
71
82
  }
83
+ } catch (error) {
84
+ graphcommerceLog(`[GraphCommerce]: An error occurred: ${error}`, 'error')
72
85
  }
73
86
  }