@syncify/cli 0.1.0-beta

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.
@@ -0,0 +1,58 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "syncify",
4
+ "version": 1.1,
5
+ "definitions": {
6
+ "schema": {
7
+ "oneOf": [
8
+ {
9
+ "type": "object",
10
+ "additionalProperties": false,
11
+ "properties": {
12
+ "domain": {
13
+ "description": "The shop domain",
14
+ "type": "string",
15
+ "default": "your-store.myshopify.com"
16
+ },
17
+ "key": {
18
+ "description": "The shop key",
19
+ "type": "string"
20
+ },
21
+ "secret": {
22
+ "description": "The shop secret",
23
+ "type": "string"
24
+ }
25
+ }
26
+ },
27
+ {
28
+ "type": "object",
29
+ "additionalProperties": false,
30
+ "properties": {
31
+ "domain": {
32
+ "description": "The shop domain",
33
+ "type": "string",
34
+ "default": "your-store.myshopify.com"
35
+ },
36
+ "token": {
37
+ "description": "The shop token",
38
+ "type": "string"
39
+ }
40
+ }
41
+ }
42
+ ]
43
+ }
44
+ },
45
+ "oneOf": [
46
+ {
47
+ "type": "object",
48
+ "$ref": "#/definitions/schema"
49
+ },
50
+ {
51
+ "type": "array",
52
+ "items": {
53
+ "type": "object",
54
+ "$ref": "#/definitions/schema"
55
+ }
56
+ }
57
+ ]
58
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "syncify",
4
+ "version": 1.1,
5
+ "type": "object",
6
+ "properties": {
7
+ "syncify": {
8
+ "$ref": "./syncify.config.json"
9
+ }
10
+ }
11
+ }
package/types/api.d.ts ADDED
@@ -0,0 +1,319 @@
1
+ import { PartialDeep } from 'type-fest';
2
+ import { Config } from './config';
3
+ import { Asset } from './misc/requests';
4
+ import { File } from './bundle/file';
5
+
6
+ type Download = (
7
+ this: {
8
+ /**
9
+ * The Shopify asset resource response
10
+ */
11
+ asset: Asset
12
+ /**
13
+ * The destination directory of the asset
14
+ */
15
+ output: string;
16
+ },
17
+ /**
18
+ * The asset contents as Buffer.
19
+ *
20
+ * > Convert to a string using `content.toString()`
21
+ */
22
+ content: Buffer
23
+ ) => (
24
+ string |
25
+ Buffer |
26
+ void |
27
+ {
28
+ /**
29
+ * Output the asset file to a new location
30
+ */
31
+ output: string;
32
+ /**
33
+ * Updated content of the asset
34
+ */
35
+ asset?: (
36
+ string |
37
+ Buffer |
38
+ object |
39
+ void
40
+ )
41
+ }
42
+ )
43
+
44
+ type Upload = (
45
+ this: File,
46
+ /**
47
+ * The file contents as Buffer.
48
+ *
49
+ * > Convert to a string using `content.toString()`
50
+ */
51
+ content: Buffer
52
+ ) => (
53
+ string |
54
+ Buffer |
55
+ void |
56
+ object
57
+ )
58
+
59
+ type Watch = (
60
+ this: File,
61
+ /**
62
+ * The file contents as Buffer.
63
+ *
64
+ * > Convert to a string using `content.toString()`
65
+ */
66
+ content: Buffer
67
+ ) => (
68
+ string |
69
+ Buffer |
70
+ void |
71
+ object
72
+ )
73
+
74
+ type Build = (
75
+ this: File,
76
+ /**
77
+ * The file contents as Buffer.
78
+ *
79
+ * > Convert to a string using `content.toString()`
80
+ */
81
+ content: Buffer
82
+ ) => (
83
+ string |
84
+ Buffer |
85
+ void |
86
+ object
87
+ )
88
+
89
+ export declare interface Resources {
90
+ /**
91
+ * Download
92
+ *
93
+ * Invoked for every asset that is downloaded from
94
+ * store theme. Use the `this` scope to access file
95
+ * information.
96
+ */
97
+ download(callback: Download): void
98
+ /**
99
+ * Upload
100
+ *
101
+ * Invoked before each file is downloaded to the
102
+ * specified store theme. Use the `this` scope to
103
+ * access file information.
104
+ */
105
+ upload(callback: Upload): void
106
+ /**
107
+ * Watch
108
+ *
109
+ * Invoked each time a file changes, after the transform
110
+ * operation has completed but before it uploaded
111
+ * to the specified store theme. Use the `this` scope to
112
+ * access file information.
113
+ */
114
+ watch(callback: Watch): void
115
+ /**
116
+ * Build
117
+ *
118
+ * Invoked after transform operation has completed in build
119
+ * mode. Use the `this` scope to access file information.
120
+ */
121
+ build(callback: Build): void
122
+ }
123
+
124
+ /**
125
+ * Syncify Utilities
126
+ *
127
+ * A couple of utilities which are helpful when working
128
+ * with external build tools or using Syncify within a script.
129
+ */
130
+ export namespace utils {
131
+
132
+ /**
133
+ * Conditional check of the current environment.
134
+ */
135
+ export function env(env: 'dev' | 'prod'): boolean
136
+
137
+ /**
138
+ * Condition check of the current running resource.
139
+ */
140
+ export function resource(resource: 'watch' | 'upload' | 'download'): boolean
141
+
142
+ }
143
+
144
+ /**
145
+ * **Syncify**
146
+ *
147
+ * The function returns a function with parameter
148
+ * Buffer value and a `this` holding file context.
149
+ * You can apply modifications to the file in pipeline by
150
+ * returning a type `string` or `Buffer`.
151
+ *
152
+ * If you return a `boolean` value `false` syncify will not
153
+ * process the file. An `undefined`, `void` or `true` return value
154
+ * will allow the file to pass through without modification.
155
+ * If the file extension is `.json` you can return an `object`.
156
+ *
157
+ * @example
158
+ *
159
+ * import syncify from '@liquify/syncify'
160
+ *
161
+ * // USING CURRY
162
+ *
163
+ * // Returns a function
164
+ * const watch = syncify('watch', {})
165
+ *
166
+ * // Hook into the transform
167
+ * watch(function (content){
168
+ *
169
+ * console.log(this) // Prints the file context to CLI
170
+ * console.log(content) // Buffer of the file
171
+ * console.log(content.toString()) // Convert the buffer to string
172
+ *
173
+ * // Update the content of the file
174
+ * return 'new value'
175
+ *
176
+ * })
177
+ *
178
+ * // USING INSTANCE
179
+ *
180
+ * // Create an instance
181
+ * const sync = syncify({})
182
+ *
183
+ * // Invoke watch mode
184
+ * sync.watch(function(content) {})
185
+ *
186
+ * // Invoke build mode
187
+ * sync.build(function(content) {})
188
+ *
189
+ * // Invoke download mode
190
+ * sync.download(function(content) {})
191
+ *
192
+ * // Invoke upload mode
193
+ * sync.upload(function(content) {})
194
+ *
195
+ * // ADDITIONAL METHODS
196
+ *
197
+ * syncify.clean()
198
+ * syncify.vsc()
199
+ * syncify.metafields()
200
+ * syncify.pages()
201
+ */
202
+ export interface Syncify {
203
+ /**
204
+ * Download
205
+ *
206
+ * Invoked for every asset that is downloaded from
207
+ * store theme. Use the `this` scope to access file
208
+ * information.
209
+ */
210
+ (resource: 'download', options?: PartialDeep<Config>): (callback: Download) => void
211
+ /**
212
+ * Upload
213
+ *
214
+ * Invoked before each file is downloaded to the
215
+ * specified store theme. Use the `this` scope to
216
+ * access file information.
217
+ */
218
+ (resource: 'upload', options?: PartialDeep<Config>): (callback: Upload) => void
219
+ /**
220
+ * Watch
221
+ *
222
+ * Invoked each time a file changes, after the transform
223
+ * operation has completed but before it uploaded
224
+ * to the specified store theme. Use the `this` scope to
225
+ * access file information.
226
+ */
227
+ (resource: 'watch', options?: PartialDeep<Config>): (callback: Watch) => void
228
+ /**
229
+ * Build
230
+ *
231
+ * Invoked after transform operation has completed in build
232
+ * mode. Use the `this` scope to access file information.
233
+ */
234
+ (resource: 'build', options?: PartialDeep<Config>): (callback: Build) => void
235
+ /**
236
+ * Usage via instance
237
+ *
238
+ * **NOT YET AVAILABLE**
239
+ */
240
+ (options?: PartialDeep<Config>): Resources
241
+ /**
242
+ * Theme resource
243
+ *
244
+ * **NOT YET AVAILABLE**
245
+ */
246
+ themes: {
247
+ push(file: string, options?: any): Promise<any>;
248
+ pull(file: string, options?: any): Promise<any>;
249
+ merge(file: string, options?: any): Promise<any>;
250
+ delete(file: string, options?: any): Promise<any>;
251
+ query(file: string, options?: any): Promise<any>
252
+ };
253
+ /**
254
+ * Assets resource
255
+ *
256
+ * **NOT YET AVAILABLE**
257
+ */
258
+ assets: {
259
+ push(file: string, options?: any): Promise<any>;
260
+ pull(file: string, options?: any): Promise<any>;
261
+ merge(file: string, options?: any): Promise<any>;
262
+ delete(file: string, options?: any): Promise<any>;
263
+ query(file: string, options?: any): Promise<any>
264
+ };
265
+ /**
266
+ * Files resource
267
+ *
268
+ * **NOT YET AVAILABLE**
269
+ */
270
+ files: {
271
+ push(file: string, options?: any): Promise<any>;
272
+ pull(file: string, options?: any): Promise<any>;
273
+ merge(file: string, options?: any): Promise<any>;
274
+ delete(file: string, options?: any): Promise<any>;
275
+ query(file: string, options?: any): Promise<any>
276
+ };
277
+ /**
278
+ * Metafields resource
279
+ *
280
+ * **NOT YET AVAILABLE**
281
+ */
282
+ metafields: {
283
+ push(file: string, options?: any): Promise<any>;
284
+ pull(file: string, options?: any): Promise<any>;
285
+ merge(file: string, options?: any): Promise<any>;
286
+ delete(file: string, options?: any): Promise<any>;
287
+ query(file: string, options?: any): Promise<any>
288
+ };
289
+ /**
290
+ * Pages resource
291
+ *
292
+ * **NOT YET AVAILABLE**
293
+ */
294
+ pages: {
295
+ push(file: string, options?: any): Promise<any>;
296
+ pull(file: string, options?: any): Promise<any>;
297
+ merge(file: string, options?: any): Promise<any>;
298
+ delete(file: string, options?: any): Promise<any>;
299
+ query(file: string, options?: any): Promise<any>
300
+ };
301
+ /**
302
+ * Update the configuration
303
+ *
304
+ * **NOT YET AVAILABLE**
305
+ */
306
+ config(options: Config): void
307
+ /**
308
+ * Clean the output directory
309
+ *
310
+ * **NOT YET AVAILABLE**
311
+ */
312
+ clean(): Promise<void>
313
+ /**
314
+ * VS Code Schema Store generation
315
+ *
316
+ * **NOT YET AVAILABLE**
317
+ */
318
+ vsc(): Promise<void>
319
+ }
@@ -0,0 +1,97 @@
1
+ export interface Cache {
2
+ /**
3
+ * The last time cache was updated at (timestamp)
4
+ */
5
+ updated: number;
6
+ /**
7
+ * When the cache was created (timestamp)
8
+ */
9
+ created: number;
10
+ /**
11
+ * Page related cache records, this reference typically
12
+ * holds `path > id` object references. Page ids are
13
+ * cached for lookup when changes occur. The `map` object
14
+ * holds the references and applied to model on initialization.
15
+ */
16
+ pages: {
17
+ /**
18
+ * The URI cache map location
19
+ *
20
+ * @default 'node_modules/.syncify/pages'
21
+ */
22
+ uri: string;
23
+ /**
24
+ * Page output name and Buffer
25
+ */
26
+ data: { [outputName: string]: Buffer }
27
+ },
28
+ /**
29
+ * Section related cache records, this reference typically
30
+ * holds output filename reference and used to prevent
31
+ * duplicated sections from being written.
32
+ */
33
+ sections: string[];
34
+ /**
35
+ * JavaScript related cache records, typically source maps
36
+ */
37
+ script: {
38
+ /**
39
+ * The URI cache map location
40
+ *
41
+ * @default 'node_modules/.syncify/script'
42
+ */
43
+ uri: string;
44
+ /**
45
+ * Metafield pathname > id cache references.
46
+ */
47
+ data: { [outputName: string]: Buffer }
48
+ },
49
+ /**
50
+ * Stylesheet related cache records, typically source maps
51
+ */
52
+ style: {
53
+ /**
54
+ * The URI cache map location
55
+ *
56
+ * @default 'node_modules/.syncify/styles'
57
+ */
58
+ uri: string;
59
+ /**
60
+ * Stylesheet output name and Buffer
61
+ */
62
+ data: { [outputName: string]: Buffer }
63
+ },
64
+ /**
65
+ * Metafields related cache records. Metafield source maps
66
+ * are `path > id` object references. Metafield ids are
67
+ * cached for lookup when changes occur. The `map` object
68
+ * holds the references and applied to model on initialization.
69
+ */
70
+ metafields: {
71
+ /**
72
+ * The URI cache reference location
73
+ *
74
+ * @default 'node_modules/.syncify/metafields'
75
+ */
76
+ uri: string,
77
+ /**
78
+ * Metafield pathname > id cache references.
79
+ */
80
+ data: { [path: string]: number }
81
+ },
82
+ /**
83
+ * Specification JSON for vscode
84
+ */
85
+ vscode: {
86
+ /**
87
+ * The URI vscode reference location
88
+ *
89
+ * @default 'node_modules/.syncify/vscode'
90
+ */
91
+ uri: string;
92
+ /**
93
+ * vscode file maps
94
+ */
95
+ data: { icons?: string; }
96
+ }
97
+ }
@@ -0,0 +1,228 @@
1
+ /* eslint-disable no-unused-vars */
2
+
3
+ import { ParsedPath } from 'path';
4
+ import { LiteralUnion } from 'type-fest';
5
+
6
+ /**
7
+ * File types are represented as numeric values.
8
+ * The infer the following:
9
+ */
10
+ export enum Types {
11
+ Template = 1,
12
+ Layout,
13
+ Snippet,
14
+ Section,
15
+ Config,
16
+ Locale,
17
+ Style,
18
+ Script,
19
+ Redirect,
20
+ File,
21
+ Svg,
22
+ Asset,
23
+ Metafield,
24
+ Page,
25
+ Spawn
26
+ }
27
+
28
+ /**
29
+ * File Kinds - Applied to `file.kind` context.
30
+ *
31
+ * _Used to describe of file being handled._
32
+ */
33
+ export type FileKinds = LiteralUnion<
34
+ | 'style'
35
+ | 'script'
36
+ | 'liquid'
37
+ | 'json'
38
+ | 'image'
39
+ | 'svg'
40
+ | 'markdown'
41
+ | 'html'
42
+ | 'redirect'
43
+ | 'video'
44
+ | 'font'
45
+ | 'document'
46
+ , string
47
+ >
48
+
49
+ /**
50
+ * Shopify Asset Key - Applied to `file.key` context
51
+ *
52
+ * _Used in REST API request payload_
53
+ */
54
+ export type FileKeys = LiteralUnion<
55
+ | `templates/${string}${'.liquid' | '.json'}`
56
+ | `templates/customer/${string}${'.liquid' | '.json'}`
57
+ | `assets/${string}`
58
+ | `sections/${string}${'.liquid'}`
59
+ | `snippets/${string}${'.liquid'}`
60
+ | `layout/${string}${'.liquid'}`
61
+ | `locales/${string}${'.json'}`
62
+ | `config/settings_${'data' | 'schema'}${'.json'}`
63
+ , string
64
+ >
65
+
66
+ /**
67
+ * File Namespace - Applied to `file.namespace` context
68
+ *
69
+ * _Used in logs, reports and other logic_
70
+ */
71
+ export type FileNamespaces = LiteralUnion<
72
+ | 'template'
73
+ | 'template/customer'
74
+ | 'snippet'
75
+ | 'section'
76
+ | 'locale'
77
+ | 'config'
78
+ | 'layout'
79
+ | 'asset'
80
+ | 'metafield'
81
+ | 'page'
82
+ | 'redirect'
83
+ | 'files'
84
+ , string
85
+ >
86
+
87
+ /**
88
+ * File Resource - Applied to `file.resource` context
89
+ *
90
+ * _Infers the REST API endpoint excepts for `files` which
91
+ * will use the insufferable Shopify GraphQL endpoint (yuck 🤮)_
92
+ */
93
+ export type FileResources = LiteralUnion<
94
+ | 'pages'
95
+ | 'redirects'
96
+ | 'assets'
97
+ | 'themes'
98
+ | 'metafields'
99
+ | 'files'
100
+ , string
101
+ >
102
+
103
+ /**
104
+ * File context generated when passed to a sync
105
+ * resource and used to dispatch to correct transform
106
+ * process.
107
+ */
108
+ interface File<T = any> extends ParsedPath {
109
+ /**
110
+ * The file type that was intercepted. This is an enum number value.
111
+ * The number value will infer on how the file should be handled.
112
+ *
113
+ * @example
114
+ *
115
+ * 1
116
+ */
117
+ type: number;
118
+ /**
119
+ * The resource endpoint to which the file will be published
120
+ *
121
+ * @example
122
+ *
123
+ * 'assets'
124
+ * 'redirects'
125
+ */
126
+ resource: FileResources;
127
+ /**
128
+ * The filename extension including the dot, eg: `.liquid`
129
+ *
130
+ * @example
131
+ *
132
+ * '.ext'
133
+ */
134
+ ext: string;
135
+ /**
136
+ * The input base filename including file extension.
137
+ *
138
+ * @example
139
+ *
140
+ * 'filename.ext'
141
+ */
142
+ base: string;
143
+ /**
144
+ * The input relative path location from current _root_ working directory
145
+ *
146
+ * @example
147
+ *
148
+ * 'source/views/sections/dir/file.liquid'
149
+ */
150
+ relative: string;
151
+ /**
152
+ * The `key` value will be passed into the sync request. This
153
+ * will contain the namespace and base name and is used for
154
+ * uploading to Shopify stores.
155
+ *
156
+ * @example
157
+ *
158
+ * 'sections/file.liquid'
159
+ * 'snippets/file.liquid'
160
+ * 'templates/index.liquid'
161
+ */
162
+ key: FileKeys;
163
+ /**
164
+ * The `namespace` value will typically refelect the output
165
+ * parent directory name reference, but sometimes this might
166
+ * be a unique value depending on the file type we are handling.
167
+ *
168
+ * @example
169
+ *
170
+ * 'snippets'
171
+ * 'sections'
172
+ * 'templates'
173
+ */
174
+ namespace: FileNamespaces;
175
+ /**
176
+ * The file kind grouping. This is used internally and describes
177
+ * the type of file we are working with.
178
+ *
179
+ * @example
180
+ *
181
+ * 'json'
182
+ * 'liquid'
183
+ * 'sass'
184
+ * 'css'
185
+ *
186
+ * // etc etc
187
+ */
188
+ kind: FileKinds
189
+ /**
190
+ * The chokidar passed path - this is full URI file path.
191
+ *
192
+ * @example
193
+ *
194
+ * 'User/name/project/source/dir/file.liquid'
195
+ */
196
+ input: string;
197
+ /**
198
+ * The output path location which files will be written.
199
+ * Only theme specific files have an output path location,
200
+ * when a file write from source (like metafield) this will
201
+ * have a `null` value.
202
+ *
203
+ * @example
204
+ *
205
+ * // When file is theme specific
206
+ * 'User/name/project/theme/dir/filename.liquid'
207
+ *
208
+ * // When file is not theme specific
209
+ * null
210
+ */
211
+ output: string;
212
+ /**
213
+ * The file size in bytes before any augmentation is applied.
214
+ *
215
+ * @example
216
+ *
217
+ * 1024 // => 1.24kb
218
+ */
219
+ size?: number;
220
+ /**
221
+ * Configuration reference. This will hold a reference
222
+ * to additional data. Typically, this is used for
223
+ * transforms, wherein it holds the indexed config.
224
+ *
225
+ * @default undefined // getter when required
226
+ */
227
+ config: T
228
+ }