@tinacms/app 0.0.26 → 0.0.27

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.
@@ -50,9 +50,10 @@ const SetPreview = ({ outputFolder }: { outputFolder: string }) => {
50
50
  }
51
51
 
52
52
  export const TinaAdminWrapper = () => {
53
+ const schema = { ...config?.schema, config }
53
54
  return (
54
55
  // @ts-ignore JSX element type 'TinaCMS' does not have any construct or call signatures.ts(2604)
55
- <TinaCMS {...config} client={{ apiUrl: __API_URL__ }}>
56
+ <TinaCMS {...config} schema={schema} client={{ apiUrl: __API_URL__ }}>
56
57
  <SetPreview outputFolder={config.build.outputFolder} />
57
58
  <TinaAdmin preview={Preview} config={config} />
58
59
  </TinaCMS>
@@ -30111,6 +30111,49 @@ function remarkMdx(options = {}) {
30111
30111
  }
30112
30112
  }
30113
30113
 
30114
+ // ../../../node_modules/.pnpm/hast-util-whitespace@2.0.0/node_modules/hast-util-whitespace/index.js
30115
+ function whitespace(thing) {
30116
+ var value = thing && typeof thing === "object" && thing.type === "text" ? thing.value || "" : thing;
30117
+ return typeof value === "string" && value.replace(/[ \t\n\f\r]/g, "") === "";
30118
+ }
30119
+
30120
+ // ../../../node_modules/.pnpm/remark-unwrap-images@3.0.1/node_modules/remark-unwrap-images/index.js
30121
+ var unknown2 = 1;
30122
+ var containsImage = 2;
30123
+ var containsOther = 3;
30124
+ function remarkUnwrapImages() {
30125
+ return (tree) => {
30126
+ visit(tree, "paragraph", (node, index2, parent) => {
30127
+ if (parent && typeof index2 === "number" && applicable(node) === containsImage) {
30128
+ parent.children.splice(index2, 1, ...node.children);
30129
+ return [SKIP, index2];
30130
+ }
30131
+ });
30132
+ };
30133
+ }
30134
+ function applicable(node, inLink) {
30135
+ let image2 = unknown2;
30136
+ let index2 = -1;
30137
+ while (++index2 < node.children.length) {
30138
+ const child = node.children[index2];
30139
+ if (whitespace(child)) {
30140
+ } else if (child.type === "image" || child.type === "imageReference") {
30141
+ image2 = containsImage;
30142
+ } else if (!inLink && (child.type === "link" || child.type === "linkReference")) {
30143
+ const linkResult = applicable(child, true);
30144
+ if (linkResult === containsOther) {
30145
+ return containsOther;
30146
+ }
30147
+ if (linkResult === containsImage) {
30148
+ image2 = containsImage;
30149
+ }
30150
+ } else {
30151
+ return containsOther;
30152
+ }
30153
+ }
30154
+ return image2;
30155
+ }
30156
+
30114
30157
  // ../../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_freeGlobal.js
30115
30158
  var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
30116
30159
  var freeGlobal_default = freeGlobal;
@@ -30510,6 +30553,8 @@ var remarkToSlate = (root3, field, imageCallback) => {
30510
30553
  return code2(content4);
30511
30554
  case "paragraph":
30512
30555
  return paragraph2(content4);
30556
+ case "image":
30557
+ return image2(content4);
30513
30558
  case "mdxJsxFlowElement":
30514
30559
  return mdxJsxElement(content4, field, imageCallback);
30515
30560
  case "thematicBreak":
@@ -30816,6 +30861,7 @@ var markdownToAst = (value, field) => {
30816
30861
  if (!tree) {
30817
30862
  throw new Error("Error parsing markdown");
30818
30863
  }
30864
+ remarkUnwrapImages({})(tree);
30819
30865
  return tree;
30820
30866
  } catch (e) {
30821
30867
  throw new RichTextParseError(e, e.position);
@@ -304,8 +304,28 @@ export const formify = async ({
304
304
  const node = G.parse(`
305
305
  query Sample {
306
306
  ...on Document {
307
+ _internalValues: _values
307
308
  _internalSys: _sys {
309
+ breadcrumbs
310
+ basename
311
+ filename
308
312
  path
313
+ extension
314
+ relativePath
315
+ title
316
+ template
317
+ collection {
318
+ name
319
+ slug
320
+ label
321
+ path
322
+ format
323
+ matches
324
+ templates
325
+ fields
326
+ __typename
327
+ }
328
+ __typename
309
329
  }
310
330
  }
311
331
  }`)
@@ -25,7 +25,7 @@ export type FormType = Form<FormValues, FieldType>
25
25
 
26
26
  export type DataType = Record<string, unknown>
27
27
 
28
- type Data = {
28
+ export type Data = {
29
29
  _internalValues: object
30
30
  _internalSys: {
31
31
  breadcrumbs: string[]
@@ -136,10 +136,14 @@ export const documentMachine =
136
136
  services: {
137
137
  initializer: async (context) => {
138
138
  const tina = context.cms.api.tina as Client
139
- const response = await tina.request<{
140
- node: Data
141
- }>(
142
- `query GetNode($id: String!) {
139
+ let node: Data
140
+ if (context.data) {
141
+ node = context.data
142
+ } else {
143
+ const response = await tina.request<{
144
+ node: Data
145
+ }>(
146
+ `query GetNode($id: String!) {
143
147
  node(id: $id) {
144
148
  ...on Document {
145
149
  _internalValues: _values
@@ -168,14 +172,16 @@ export const documentMachine =
168
172
  }
169
173
  }
170
174
  }`,
171
- { variables: { id: context.id } }
172
- )
175
+ { variables: { id: context.id } }
176
+ )
177
+ node = response.node
178
+ }
173
179
  const schema = context.cms.api.tina.schema as TinaSchema
174
180
  if (!schema) {
175
181
  throw new Error(`Schema must be provided`)
176
182
  }
177
183
  const collection = schema.getCollection(
178
- response.node._internalSys.collection.name
184
+ node._internalSys.collection.name
179
185
  )
180
186
  let template: Templateable
181
187
  if (collection.templates) {
@@ -183,19 +189,19 @@ export const documentMachine =
183
189
  if (typeof template === 'string') {
184
190
  throw new Error(`Global templates not supported`)
185
191
  }
186
- return template.name === response.node._internalSys.template
192
+ return template.name === node._internalSys.template
187
193
  }) as Templateable
188
194
  } else {
189
195
  template = collection
190
196
  }
191
197
  if (!template) {
192
198
  throw new Error(
193
- `Unable to find template for node ${response.node._internalSys.path}`
199
+ `Unable to find template for node ${node._internalSys.path}`
194
200
  )
195
201
  }
196
202
  const resolvedForm = resolveForm({
197
203
  collection,
198
- basename: response.node._internalSys.filename,
204
+ basename: node._internalSys.filename,
199
205
  schema,
200
206
  template,
201
207
  })
@@ -211,10 +217,10 @@ export const documentMachine =
211
217
 
212
218
  await context.cms.api.tina.request(mutationString, {
213
219
  variables: {
214
- collection: response.node._internalSys.collection.name,
215
- relativePath: response.node._internalSys.relativePath,
220
+ collection: node._internalSys.collection.name,
221
+ relativePath: node._internalSys.relativePath,
216
222
  params: schema.transformPayload(
217
- response.node._internalSys.collection.name,
223
+ node._internalSys.collection.name,
218
224
  payload
219
225
  ),
220
226
  },
@@ -230,9 +236,8 @@ export const documentMachine =
230
236
  const formConfig = {
231
237
  id: context.id,
232
238
  label:
233
- response.node._internalSys.title ||
234
- response.node._internalSys.collection.label,
235
- initialValues: response.node._internalValues,
239
+ node._internalSys.title || node._internalSys.collection.label,
240
+ initialValues: node._internalValues,
236
241
  fields: resolvedForm.fields,
237
242
  onSubmit,
238
243
  }
@@ -250,7 +255,7 @@ export const documentMachine =
250
255
  true,
251
256
  onSubmit
252
257
  )
253
- return { form, data: response.node }
258
+ return { form, data: node }
254
259
  },
255
260
  },
256
261
  }
@@ -10,12 +10,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
10
  See the License for the specific language governing permissions and
11
11
  limitations under the License.
12
12
  */
13
- import { assign, ContextFrom, createMachine, spawn } from 'xstate'
13
+ import { assign, createMachine, spawn } from 'xstate'
14
14
  import {
15
15
  Form,
16
16
  TinaCMS,
17
17
  NAMER,
18
- Template,
19
18
  TinaFieldEnriched,
20
19
  TinaCollection,
21
20
  TinaSchema,
@@ -24,9 +23,8 @@ import {
24
23
  } from 'tinacms'
25
24
  import * as G from 'graphql'
26
25
  import { formify } from '../formify'
27
- import { documentMachine, FieldType, FormValues } from './document-machine'
26
+ import { Data, documentMachine } from './document-machine'
28
27
  import type { ActorRefFrom } from 'xstate'
29
- import { Blueprint2 } from '../formify'
30
28
 
31
29
  export type DataType = Record<string, unknown>
32
30
  type DocumentInfo = {
@@ -43,18 +41,21 @@ type ContextType = {
43
41
  id: null | string
44
42
  data: null | DataType
45
43
  cms: TinaCMS
46
- selectedDocument: string | null
44
+ documentNode: G.DocumentNode
45
+ variables: object
47
46
  iframe: null | HTMLIFrameElement
47
+ registerSubForms?: boolean
48
48
  formifyCallback: (args: any) => Form
49
49
  documentMap: DocumentMap
50
- blueprints: Blueprint2[]
50
+ documents: Data[]
51
51
  }
52
52
  export const initialContext: Omit<ContextType, 'cms' | 'formifyCallback'> = {
53
53
  id: null,
54
54
  data: null,
55
- selectedDocument: null,
56
- blueprints: [],
55
+ variables: {},
57
56
  documentMap: {},
57
+ documents: [],
58
+ documentNode: { kind: 'Document', definitions: [] },
58
59
  iframe: null,
59
60
  }
60
61
  export const queryMachine =
@@ -68,7 +69,6 @@ export const queryMachine =
68
69
  initializer: {
69
70
  data: {
70
71
  data: DataType
71
- blueprints: Blueprint2[]
72
72
  }
73
73
  }
74
74
  setter: {
@@ -197,9 +197,6 @@ export const queryMachine =
197
197
  REMOVE_QUERY: {
198
198
  target: 'idle',
199
199
  },
200
- SELECT_DOCUMENT: {
201
- actions: 'selectDocument',
202
- },
203
200
  FIELD_CHANGE: {
204
201
  target: 'pending',
205
202
  },
@@ -214,10 +211,6 @@ export const queryMachine =
214
211
  actions: {
215
212
  handleError: (_context, event) => console.error(event.data),
216
213
  handleMissingDocument: assign((context, event) => {
217
- count = count + 1
218
- if (count > 50) {
219
- throw new Error('infinite loop')
220
- }
221
214
  if (event.data instanceof QueryError) {
222
215
  if (context.documentMap[event.data.id]) {
223
216
  // Already exists
@@ -226,6 +219,9 @@ export const queryMachine =
226
219
  if (!event.data.id) {
227
220
  return context
228
221
  }
222
+ const existingData = context.documents.find(
223
+ (doc) => doc._internalSys.path === event.data.id
224
+ )
229
225
  const doc = {
230
226
  ref: spawn(
231
227
  documentMachine.withContext({
@@ -233,7 +229,7 @@ export const queryMachine =
233
229
  cms: context.cms,
234
230
  formifyCallback: context.formifyCallback,
235
231
  form: null,
236
- data: null,
232
+ data: existingData || null,
237
233
  })
238
234
  ),
239
235
  }
@@ -271,12 +267,6 @@ export const queryMachine =
271
267
  ...event.data,
272
268
  }
273
269
  }),
274
- selectDocument: assign((context, event) => {
275
- return {
276
- ...context,
277
- selectedDocument: event.value,
278
- }
279
- }),
280
270
  setIframe: assign((context, event) => {
281
271
  return {
282
272
  ...context,
@@ -299,41 +289,110 @@ export const queryMachine =
299
289
  },
300
290
  services: {
301
291
  setter: async (context) => {
302
- const walk = (obj: unknown, path: string[] = []) => {
303
- const accum: Record<string, unknown> = {}
304
- if (isScalar(obj)) {
305
- return obj
306
- }
307
- Object.entries(obj as object).map(([key, value]) => {
308
- if (Array.isArray(value)) {
309
- accum[key] = value.map((item) => walk(item, [...path, key]))
310
- } else {
311
- const blueprint = context.blueprints.find(
312
- (bp) => bp.path?.join('.') === [...path, key].join('.')
313
- )
314
- if (blueprint) {
315
- accum[key] = setData(value, blueprint, context)
292
+ const tinaSchema = context.cms.api.tina.schema as TinaSchema
293
+ const gqlSchema = context.cms.api.tina.gqlSchema
294
+ const missingForms: { id: string; skipFormRegister: boolean }[] = []
295
+ const newData = await G.graphql({
296
+ schema: gqlSchema,
297
+ source: G.print(context.documentNode),
298
+ rootValue: context.data,
299
+ variableValues: context.variables,
300
+ fieldResolver: (source, args, _context, info) => {
301
+ const fieldName = info.fieldName
302
+ /**
303
+ * Formify adds `_internalSys` and `_internalValues` to the query
304
+ * and a user's query might also include `_values` or `_sys`, but
305
+ * it may not contain all of the info we need, so the actual
306
+ * source of truth for these values is our alias ones, which are
307
+ * also guaranteed to include all of the values another `_sys` query
308
+ * might include
309
+ */
310
+ if (fieldName === '_sys') {
311
+ return source._internalSys
312
+ }
313
+ if (fieldName === '_values') {
314
+ return source._internalValues
315
+ }
316
+ if (isNodeType(info.returnType)) {
317
+ const existingValue = source[fieldName]
318
+ let skipFormRegister = false
319
+ if (!existingValue) {
320
+ return null
321
+ }
322
+ let path: string = ''
323
+ if (typeof existingValue === 'string') {
324
+ // this is a reference value (eg. post.author)
325
+ skipFormRegister = true
326
+ path = existingValue
327
+ } else {
328
+ path = existingValue._internalSys.path
329
+ }
330
+ if (context.documentMap[path]) {
331
+ const documentMachine = context.documentMap[path].ref
332
+ const documentContext = documentMachine.getSnapshot()?.context
333
+ if (!documentContext) {
334
+ throw new Error(
335
+ `Document not set up properly for id: ${path}`
336
+ )
337
+ }
338
+ const { data, form } = documentContext
339
+ const values = form?.values
340
+ if (!data || !form || !values) {
341
+ throw new Error(
342
+ `Document not set up properly for id: ${path}`
343
+ )
344
+ }
345
+ const collectionName = data._internalSys.collection.name
346
+ const extraValues = documentContext.data
347
+ const formVal = resolveFormValue({
348
+ fields: form.fields,
349
+ values: values,
350
+ tinaSchema,
351
+ })
352
+ const template = tinaSchema.getTemplateForData({
353
+ data: form.values,
354
+ collection: tinaSchema.getCollection(collectionName),
355
+ })
356
+ return {
357
+ ...extraValues,
358
+ ...formVal,
359
+ _sys: data._internalSys,
360
+ id: path,
361
+ __typename: NAMER.dataTypeName(template.namespace),
362
+ }
316
363
  } else {
317
- accum[key] = walk(value, [...path, key])
364
+ // TODO: when we support forms in lists, remove this check
365
+ // This checks that we're at least 2 levels deep, meaning top-level
366
+ // queries list page(relativePath: '...') will be registered, but
367
+ // not connection nodes like pageConnection.edges.node
368
+ if (info.path?.prev?.prev) {
369
+ skipFormRegister = true
370
+ }
371
+ missingForms.push({ id: path, skipFormRegister })
372
+ return null
318
373
  }
319
374
  }
320
- })
321
- return accum
375
+ return source[fieldName]
376
+ },
377
+ })
378
+ if (missingForms.length > 0) {
379
+ // Only run this one at a time
380
+ const missingForm = missingForms[0]
381
+ throw new QueryError(
382
+ `Unable to resolve form for initial document`,
383
+ missingForm.id,
384
+ missingForm.skipFormRegister
385
+ )
322
386
  }
323
- const accum = walk(context.data)
324
- return { data: accum }
387
+ return { data: newData.data }
325
388
  },
326
389
  initializer: async (context, event) => {
327
390
  const tina = context.cms.api.tina as Client
328
391
  const schema = await tina.getSchema()
329
392
  const documentNode = G.parse(event.value.query)
330
- const optimizedQuery = await tina.getOptimizedQuery(documentNode)
331
- if (!optimizedQuery) {
332
- throw new Error(`Unable to optimize query`)
333
- }
334
- const { blueprints, formifiedQuery } = await formify({
393
+ const { formifiedQuery } = await formify({
335
394
  schema,
336
- optimizedDocumentNode: optimizedQuery,
395
+ optimizedDocumentNode: documentNode,
337
396
  })
338
397
  const data = (await context.cms.api.tina.request(
339
398
  G.print(formifiedQuery),
@@ -341,17 +400,29 @@ export const queryMachine =
341
400
  variables: event.value.variables,
342
401
  }
343
402
  )) as DataType
403
+ const documents: Data[] = []
404
+ // step through every value in the payload to find the documents
405
+ JSON.stringify(data, (key, value) => {
406
+ if (value?._internalValues) {
407
+ documents.push(value)
408
+ }
409
+ return value
410
+ })
344
411
  return {
345
412
  data,
346
- blueprints,
413
+ documents,
414
+ variables: event.value.variables,
415
+ documentNode: formifiedQuery,
347
416
  id: event.value.id,
348
417
  }
349
418
  },
350
419
  onChangeCallback: (context) => (callback, _onReceive) => {
351
420
  const schema = context.cms.api.tina.schema as TinaSchema
352
421
  Object.values(context.documentMap).forEach((documentMachine) => {
353
- if (documentMachine.skipFormRegister) {
354
- return
422
+ if (!context.registerSubForms) {
423
+ if (documentMachine.skipFormRegister) {
424
+ return
425
+ }
355
426
  }
356
427
  const documentContext = documentMachine.ref.getSnapshot()?.context
357
428
  const collectionName =
@@ -397,242 +468,121 @@ class QueryError extends Error {
397
468
  this.skipFormRegister = skipFormRegister
398
469
  }
399
470
  }
400
- let count = 0
401
-
402
- // https://github.com/oleics/node-is-scalar/blob/master/index.js
403
- const withSymbol = typeof Symbol !== 'undefined'
404
- function isScalar(value: unknown) {
405
- const type = typeof value
406
- if (type === 'string') return true
407
- if (type === 'number') return true
408
- if (type === 'boolean') return true
409
- if (withSymbol === true && type === 'symbol') return true
410
471
 
411
- if (value == null) return true
412
- if (withSymbol === true && value instanceof Symbol) return true
413
- if (value instanceof String) return true
414
- if (value instanceof Number) return true
415
- if (value instanceof Boolean) return true
416
-
417
- return false
418
- }
419
-
420
- const setData = (
421
- data: { [key: string]: unknown },
422
- blueprint: Blueprint2,
423
- context: ContextFrom<typeof queryMachine>
424
- ) => {
425
- if (data?._internalSys) {
426
- const id = data._internalSys?.path
427
- const doc = context.documentMap[id]
428
- const docContext = doc?.ref?.getSnapshot()?.context
429
- const form = docContext?.form
430
- if (!form) {
431
- const skipFormRegiester = (blueprint.path?.length || 0) > 2
432
- throw new QueryError(
433
- `Unable to resolve form for initial document`,
434
- id,
435
- skipFormRegiester
436
- )
472
+ const isNodeType = (type: G.GraphQLOutputType) => {
473
+ const namedType = G.getNamedType(type)
474
+ if (G.isInterfaceType(namedType)) {
475
+ if (namedType.name === 'Node') {
476
+ return true
437
477
  }
438
- const _internalSys = docContext.data?._internalSys
439
- if (!_internalSys) {
440
- throw new Error(`No system information found for document ${id}`)
478
+ }
479
+ if (G.isUnionType(namedType)) {
480
+ const types = namedType.getTypes()
481
+ if (
482
+ types.every((type) => {
483
+ return type.getInterfaces().some((intfc) => intfc.name === 'Node')
484
+ })
485
+ ) {
486
+ return true
487
+ }
488
+ }
489
+ if (G.isObjectType(namedType)) {
490
+ if (namedType.getInterfaces().some((intfc) => intfc.name === 'Node')) {
491
+ return true
441
492
  }
442
-
443
- const fields = form.fields
444
- const result = resolveForm({
445
- id,
446
- fields,
447
- sys: _internalSys,
448
- values: form.values,
449
- fieldsToInclude: blueprint.fields,
450
- context,
451
- })
452
- return { ...docContext.data, ...result }
453
- } else {
454
- // this isn't a node
455
493
  }
456
- return data
457
494
  }
458
495
 
459
- const resolveForm = ({
460
- id,
496
+ const resolveFormValue = <T extends Record<string, unknown>>({
461
497
  fields,
462
- sys,
463
498
  values,
464
- fieldsToInclude,
465
- context,
499
+ tinaSchema,
466
500
  }: {
467
- id: string
468
- fields: FieldType[]
469
- sys: Record<string, unknown>
470
- values: FormValues | undefined
471
- fieldsToInclude: Blueprint2['fields']
472
- context: ContextFrom<typeof queryMachine>
473
- }) => {
501
+ fields: TinaFieldEnriched[]
502
+ values: T
503
+ tinaSchema: TinaSchema
504
+ }): T & { __typename?: string } => {
474
505
  const accum: Record<string, unknown> = {}
475
- if (!values) {
476
- return accum
477
- }
478
-
479
- fieldsToInclude?.forEach((fieldToInclude) => {
480
- const field = fields.find((field) => fieldToInclude.name === field.name)
481
- if (!field) {
482
- if (fieldToInclude.name === 'id') {
483
- accum[fieldToInclude.alias] = id
484
- } else if (fieldToInclude.name === '_sys') {
485
- if (fieldToInclude.alias !== '_internalSys') {
486
- const sysAccum: Record<string, unknown> = {}
487
- // TODO: loop through these and actually use their alias values
488
- fieldToInclude.fields?.forEach((field) => {
489
- sysAccum[field.alias] = sys[field.name]
490
- })
491
- accum[fieldToInclude.alias] = sysAccum
492
- }
493
- } else if (fieldToInclude.name === '__typename') {
494
- // field namespaces are one level deeper than what we need, so grab the first
495
- // one and remove the last string on the namespace
496
- accum[fieldToInclude.alias] = NAMER.dataTypeName(
497
- fields[0].namespace.slice(0, fields[0].namespace.length - 1)
498
- )
499
- } else if (fieldToInclude.name === '_values') {
500
- if (fieldToInclude.alias !== '_internalValues') {
501
- accum[fieldToInclude.alias] = values
502
- }
503
- } else {
504
- }
505
- } else {
506
- const result = resolveField({
507
- id,
508
- field,
509
- sys,
510
- value: values[field.name],
511
- fieldsToInclude: fieldsToInclude.find(({ name }) => name === field.name)
512
- ?.fields,
513
- context,
514
- })
515
- if (result) {
516
- accum[fieldToInclude.alias] = result
517
- }
506
+ fields.forEach((field) => {
507
+ const v = values[field.name]
508
+ if (!v) {
509
+ return
518
510
  }
511
+ accum[field.name] = resolveFieldValue({
512
+ field,
513
+ value: v,
514
+ tinaSchema,
515
+ })
519
516
  })
520
-
521
- return accum
517
+ return accum as T & { __typename?: string }
522
518
  }
523
- const resolveField = ({
524
- id,
519
+ const resolveFieldValue = ({
525
520
  field,
526
- sys,
527
521
  value,
528
- fieldsToInclude,
529
- context,
522
+ tinaSchema,
530
523
  }: {
531
- id: string
532
524
  field: TinaFieldEnriched
533
- sys: Record<string, unknown>
534
525
  value: unknown
535
- fieldsToInclude: Blueprint2['fields']
536
- context: ContextFrom<typeof queryMachine>
526
+ tinaSchema: TinaSchema
537
527
  }) => {
538
528
  switch (field.type) {
539
- case 'reference':
540
- if (!value) {
541
- return
542
- }
543
- if (typeof value === 'string') {
544
- const doc = context.documentMap[value]
545
- const docContext = doc?.ref?.getSnapshot()?.context
546
- const form = docContext?.form
547
- if (!form) {
548
- throw new QueryError(
549
- `Unable to resolve form for document`,
550
- value,
551
- true
552
- )
553
- }
554
- const _internalSys = docContext.data?._internalSys
555
- if (!_internalSys) {
556
- throw new Error(`No system information found for document ${id}`)
557
- }
558
- return resolveForm({
559
- id: value,
560
- fields: form.fields,
561
- sys: _internalSys,
562
- values: form.values,
563
- fieldsToInclude,
564
- context,
565
- })
566
- }
567
- throw new Error(`Unexpected value for type "reference"`)
568
- case 'object':
569
- if (field.fields) {
570
- if (typeof field.fields === 'string') {
571
- throw new Error('Global templates not supported')
572
- }
573
- field.fields
529
+ case 'object': {
530
+ if (field.templates) {
574
531
  if (field.list) {
575
532
  if (Array.isArray(value)) {
576
533
  return value.map((item) => {
577
- if (typeof field.fields === 'string') {
534
+ const template = field.templates[item._template]
535
+ if (typeof template === 'string') {
578
536
  throw new Error('Global templates not supported')
579
537
  }
580
- return resolveForm({
581
- id,
582
- fields: field.fields,
583
- sys,
584
- values: item,
585
- fieldsToInclude,
586
- context,
587
- })
538
+ return {
539
+ __typename: NAMER.dataTypeName(template.namespace),
540
+ ...resolveFormValue({
541
+ fields: template.fields,
542
+ values: item,
543
+ tinaSchema,
544
+ }),
545
+ }
588
546
  })
589
547
  }
590
548
  } else {
591
- return resolveForm({
592
- id,
593
- fields: field.fields,
594
- sys,
595
- values: value,
596
- fieldsToInclude,
597
- context,
598
- })
549
+ // not implemented
599
550
  }
600
551
  }
601
- if (field.templates) {
602
- if (field.list) {
603
- if (!value) {
604
- return
605
- }
606
- if (!Array.isArray(value)) {
607
- return
608
- }
552
+
553
+ const templateFields = field.fields
554
+ if (typeof templateFields === 'string') {
555
+ throw new Error('Global templates not supported')
556
+ }
557
+ if (!templateFields) {
558
+ throw new Error(`Expected to find sub-fields on field ${field.name}`)
559
+ }
560
+ if (field.list) {
561
+ if (Array.isArray(value)) {
609
562
  return value.map((item) => {
610
- let t: Template<true>
611
- Object.entries(field.templates).forEach(([name, template]) => {
612
- if (name === item._template) {
613
- if (typeof template === 'string') {
614
- throw new Error('Global templates not supported')
615
- }
616
- t = template
617
- }
618
- })
619
563
  return {
620
- _template: item._template,
621
- ...resolveForm({
622
- id,
623
- fields: t.fields,
624
- sys,
564
+ __typename: NAMER.dataTypeName(field.namespace),
565
+ ...resolveFormValue({
566
+ fields: templateFields,
625
567
  values: item,
626
- fieldsToInclude,
627
- context,
568
+ tinaSchema,
628
569
  }),
629
570
  }
630
571
  })
631
- } else {
632
- // not supported yet
572
+ }
573
+ } else {
574
+ return {
575
+ __typename: NAMER.dataTypeName(field.namespace),
576
+ ...resolveFormValue({
577
+ fields: templateFields,
578
+ values: value as any,
579
+ tinaSchema,
580
+ }),
633
581
  }
634
582
  }
635
- default:
583
+ }
584
+ default: {
636
585
  return value
586
+ }
637
587
  }
638
588
  }
@@ -80,6 +80,8 @@ const QueryMachine = (props: {
80
80
  queryMachine.withContext({
81
81
  ...initialContext,
82
82
  cms,
83
+ // Enable registration of sub forms
84
+ // registerSubForms: true,
83
85
  // @ts-ignore FIXME: add formifyCallback args to Config type
84
86
  formifyCallback: props.formifyCallback,
85
87
  }),
@@ -270,8 +270,28 @@ var formify = async ({
270
270
  var node = G.parse(`
271
271
  query Sample {
272
272
  ...on Document {
273
+ _internalValues: _values
273
274
  _internalSys: _sys {
275
+ breadcrumbs
276
+ basename
277
+ filename
274
278
  path
279
+ extension
280
+ relativePath
281
+ title
282
+ template
283
+ collection {
284
+ name
285
+ slug
286
+ label
287
+ path
288
+ format
289
+ matches
290
+ templates
291
+ fields
292
+ __typename
293
+ }
294
+ __typename
275
295
  }
276
296
  }
277
297
  }`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinacms/app",
3
- "version": "0.0.26",
3
+ "version": "0.0.27",
4
4
  "main": "dist/index.js",
5
5
  "exports": {
6
6
  ".": {
@@ -37,8 +37,8 @@
37
37
  "@types/react": "17.0.2",
38
38
  "@types/react-dom": "17.0.2",
39
39
  "@tinacms/scripts": "0.51.3",
40
- "tinacms": "0.70.0",
41
- "@tinacms/mdx": "0.61.15",
40
+ "tinacms": "0.70.1",
41
+ "@tinacms/mdx": "0.61.16",
42
42
  "jest": "^27.0.6"
43
43
  },
44
44
  "dependencies": {