@carthooks/arcubase-cli 0.1.24 → 0.1.25

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,360 +1,20 @@
1
- import { CLIError } from './errors.js'
2
-
3
- export type GeneratedSDKFile = {
4
- path: string
5
- contents: string
6
- }
7
-
8
- export type GeneratedSDK = {
9
- files: GeneratedSDKFile[]
10
- }
11
-
12
- type ArcubaseField = {
13
- id: number
14
- label: string
15
- key: string
16
- type: string
17
- required: boolean
18
- options?: Record<string, unknown>
19
- }
20
-
21
- type ArcubaseEntity = {
22
- appId: number
23
- id: number
24
- name: string
25
- sdkName: string
26
- fields: ArcubaseField[]
27
- }
28
-
29
- function isRecord(value: unknown): value is Record<string, any> {
30
- return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
31
- }
32
-
33
- function unwrapData(payload: unknown): unknown {
34
- return isRecord(payload) && 'data' in payload ? payload.data : payload
35
- }
36
-
37
- function toPascalCase(value: string): string {
38
- const words = value
39
- .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
40
- .split(/[^A-Za-z0-9]+/)
41
- .filter(Boolean)
42
- if (words.length === 0) return 'Entity'
43
- return words.map((word) => `${word[0].toUpperCase()}${word.slice(1)}`).join('')
44
- }
45
-
46
- function toCamelCase(value: string): string {
47
- const pascal = toPascalCase(value)
48
- return `${pascal[0].toLowerCase()}${pascal.slice(1)}`
49
- }
50
-
51
- function sanitizeEntityKey(entity: ArcubaseEntity): string {
52
- const fallback = entity.sdkName || `entity_${entity.id}`
53
- return toCamelCase(fallback) === 'entity' ? `entity${entity.id}` : toCamelCase(fallback)
54
- }
55
-
56
- function normalizeFieldType(type: string): string {
57
- switch (type) {
58
- case 'number':
59
- return 'number'
60
- case 'boolean':
61
- return 'boolean'
62
- case 'select':
63
- case 'radio':
64
- case 'checkbox':
65
- case 'status':
66
- return 'number | string'
67
- case 'file':
68
- case 'image':
69
- case 'member':
70
- case 'members':
71
- case 'department':
72
- case 'departments':
73
- case 'linkto':
74
- case 'relation':
75
- case 'relationfield':
76
- case 'subform':
77
- return 'unknown'
78
- default:
79
- return 'string'
80
- }
81
- }
82
-
83
- function normalizeEntities(payload: unknown): ArcubaseEntity[] {
84
- const root = unwrapData(payload)
85
- if (!isRecord(root)) {
86
- throw new CLIError('SDK_GEN_INVALID_SCHEMA', 'sdk-gen expected an app detail object', 2)
87
- }
88
- const appId = typeof root.id === 'number' ? root.id : typeof root.app_id === 'number' ? root.app_id : undefined
89
- if (!appId) {
90
- throw new CLIError('SDK_GEN_APP_ID_REQUIRED', 'sdk-gen expected app id in app detail response', 2)
91
- }
92
- const sourceEntities = Array.isArray(root.entities)
93
- ? root.entities
94
- : Array.isArray(root.tables)
95
- ? root.tables
96
- : Array.isArray(root.entitys)
97
- ? root.entitys
98
- : []
99
- const entities = sourceEntities
100
- .filter((item): item is Record<string, unknown> => isRecord(item))
101
- .filter((item) => typeof item.id === 'number' && typeof item.name === 'string')
102
- .map((item) => {
103
- const fields = Array.isArray(item.fields)
104
- ? item.fields
105
- .filter((field): field is Record<string, unknown> => isRecord(field))
106
- .filter((field) => typeof field.id === 'number' && typeof field.label === 'string' && typeof field.type === 'string')
107
- .map((field) => ({
108
- id: field.id as number,
109
- label: field.label as string,
110
- key: typeof field.key === 'string' ? field.key.trim() : '',
111
- type: field.type as string,
112
- required: field.required === true,
113
- options: isRecord(field.options) ? field.options : undefined,
114
- }))
115
- : []
116
- const entity: ArcubaseEntity = {
117
- appId,
118
- id: item.id as number,
119
- name: item.name as string,
120
- sdkName: typeof item.key === 'string' && item.key.trim() ? item.key.trim() : '',
121
- fields,
122
- }
123
- entity.sdkName = sanitizeEntityKey(entity)
124
- return entity
125
- })
126
- if (entities.length === 0) {
127
- throw new CLIError('SDK_GEN_NO_ENTITIES', 'sdk-gen could not find entities in app detail response', 2)
128
- }
129
- validateEntities(entities)
130
- return entities
131
- }
132
-
133
- function validateEntities(entities: ArcubaseEntity[]) {
134
- const entityKeys = new Set<string>()
135
- for (const entity of entities) {
136
- if (entityKeys.has(entity.sdkName)) {
137
- throw new CLIError('SDK_GEN_DUPLICATE_ENTITY_KEY', `duplicate generated entity key: ${entity.sdkName}`, 2)
138
- }
139
- entityKeys.add(entity.sdkName)
140
-
141
- const fieldKeys = new Set<string>()
142
- for (const field of entity.fields) {
143
- if (!field.key) {
144
- throw new CLIError('SDK_GEN_FIELD_KEY_REQUIRED', `field.key is required for ${entity.name}.${field.label} (${field.id})`, 2)
145
- }
146
- if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(field.key)) {
147
- throw new CLIError('SDK_GEN_INVALID_FIELD_KEY', `field.key must be a TypeScript identifier: ${entity.name}.${field.key}`, 2)
148
- }
149
- if (fieldKeys.has(field.key)) {
150
- throw new CLIError('SDK_GEN_DUPLICATE_FIELD_KEY', `duplicate field.key in ${entity.name}: ${field.key}`, 2)
151
- }
152
- fieldKeys.add(field.key)
153
- }
154
- }
155
- }
156
-
157
- function emitRuntime(): string {
158
- return `export type ArcubaseSdkConfig = {
159
- baseURL: string
160
- accessToken?: string
161
- refreshToken?: string
162
- }
163
-
164
- export type ArcubaseRow<TFields> = {
165
- id: number
166
- title?: string
167
- fields: TFields
168
- raw: Record<string, any>
169
- }
170
-
171
- export type ArcubaseRuntime = {
172
- config: ArcubaseSdkConfig
173
- request<T>(method: string, endpoint: string, body?: unknown): Promise<T>
174
- }
175
-
176
- type ArcubaseEnvelope<T> = {
177
- data?: T
178
- error?: { message?: string; key?: string; type?: string }
179
- }
180
-
181
- export function createRuntime(config: ArcubaseSdkConfig): ArcubaseRuntime {
182
- let accessToken = config.accessToken ?? ''
183
- let refreshToken = config.refreshToken ?? ''
1
+ import {
2
+ ArcubaseCodeGenError,
3
+ generateArcubaseProjectSDK as generateArcubaseProjectSDKCore,
4
+ type GeneratedSDK,
5
+ } from '@arcubase/code-gen'
184
6
 
185
- async function request<T>(method: string, endpoint: string, body?: unknown): Promise<T> {
186
- const baseURL = config.baseURL.endsWith('/') ? config.baseURL : \`\${config.baseURL}/\`
187
- const response = await fetch(new URL(endpoint.replace(/^\\/+/, ''), baseURL).toString(), {
188
- method,
189
- headers: {
190
- 'Content-Type': 'application/json',
191
- ...(accessToken ? { Authorization: \`Bearer \${accessToken}\` } : {}),
192
- },
193
- body: body === undefined ? undefined : JSON.stringify(body),
194
- })
195
- const payload = await response.json().catch(() => null) as ArcubaseEnvelope<T> | null
196
- if (!response.ok || payload?.error) {
197
- throw new Error(payload?.error?.message ?? \`Arcubase request failed: \${response.status}\`)
198
- }
199
- return payload?.data as T
200
- }
201
-
202
- return {
203
- config: { ...config, accessToken, refreshToken },
204
- request,
205
- }
206
- }
207
- `
208
- }
209
-
210
- function emitSchema(entities: ArcubaseEntity[]): string {
211
- const schema = {
212
- entities: Object.fromEntries(entities.map((entity) => [
213
- entity.sdkName,
214
- {
215
- entityId: entity.id,
216
- name: entity.name,
217
- fields: Object.fromEntries(entity.fields.map((field) => [
218
- field.key,
219
- {
220
- fieldId: field.id,
221
- label: field.label,
222
- type: field.type,
223
- required: field.required,
224
- },
225
- ])),
226
- },
227
- ])),
228
- }
229
- return `export const arcubaseSchema = ${JSON.stringify(schema, null, 2)} as const
230
-
231
- export type ArcubaseEntityKey = keyof typeof arcubaseSchema.entities
232
- `
233
- }
234
-
235
- function emitEntity(entity: ArcubaseEntity): string {
236
- const typeName = toPascalCase(entity.sdkName)
237
- const fieldLines = entity.fields.map((field) => {
238
- const optional = field.required ? '' : '?'
239
- return ` ${field.key}${optional}: ${normalizeFieldType(field.type)}`
240
- })
241
- const fieldMapLines = entity.fields.map((field) => ` ${field.key}: ${field.id},`)
242
-
243
- return `import type { ArcubaseRuntime, ArcubaseRow } from '../runtime.js'
244
-
245
- export type ${typeName}Fields = {
246
- ${fieldLines.join('\n')}
247
- }
248
-
249
- export type ${typeName}CreateInput = ${typeName}Fields
250
- export type ${typeName}UpdateInput = Partial<${typeName}Fields>
251
-
252
- const entityId = ${entity.id}
253
- const fieldIds = {
254
- ${fieldMapLines.join('\n')}
255
- } as const
256
-
257
- function toArcubaseFields(fields: Partial<${typeName}Fields>): Record<string, any> {
258
- const out: Record<string, any> = {}
259
- for (const [key, value] of Object.entries(fields)) {
260
- if (value === undefined) continue
261
- const fieldId = fieldIds[key as keyof typeof fieldIds]
262
- if (!fieldId) {
263
- throw new Error(\`Unknown ${entity.sdkName} field: \${key}\`)
264
- }
265
- out[String(fieldId)] = value
266
- }
267
- return out
268
- }
269
-
270
- function fromArcubaseFields(raw: Record<string, any> | undefined): ${typeName}Fields {
271
- const out: Record<string, any> = {}
272
- const source = raw ?? {}
273
- for (const [key, fieldId] of Object.entries(fieldIds)) {
274
- if (String(fieldId) in source) {
275
- out[key] = source[String(fieldId)]
276
- }
277
- }
278
- return out as ${typeName}Fields
279
- }
280
-
281
- function mapRow(raw: Record<string, any>): ArcubaseRow<${typeName}Fields> {
282
- return {
283
- id: Number(raw.id),
284
- title: typeof raw.title === 'string' ? raw.title : undefined,
285
- fields: fromArcubaseFields(raw.fields),
286
- raw,
287
- }
288
- }
289
-
290
- export function create${typeName}SDK(runtime: ArcubaseRuntime) {
291
- return {
292
- async create(fields: ${typeName}CreateInput): Promise<number> {
293
- return runtime.request<number>('POST', \`/entity/${entity.appId}/\${entityId}/insert\`, {
294
- fields: toArcubaseFields(fields),
295
- })
296
- },
297
-
298
- async update(rowId: string | number, fields: ${typeName}UpdateInput): Promise<boolean> {
299
- const data = toArcubaseFields(fields)
300
- return runtime.request<boolean>('PUT', \`/entity/${entity.appId}/\${entityId}/row/\${rowId}\`, {
301
- data,
302
- changed_fields: Object.keys(data).map((fieldId) => Number(fieldId)),
303
- })
304
- },
305
-
306
- async get(rowId: string | number): Promise<ArcubaseRow<${typeName}Fields>> {
307
- const data = await runtime.request<{ record?: Record<string, any> }>('GET', \`/entity/${entity.appId}/\${entityId}/row/\${rowId}\`)
308
- return mapRow(data.record ?? {})
309
- },
310
-
311
- async query(params: { limit?: number; offset?: number; search?: Record<string, any> } = {}): Promise<{ items: ArcubaseRow<${typeName}Fields>[]; total?: number }> {
312
- const data = await runtime.request<{ items?: Record<string, any>[]; total?: number }>('POST', \`/entity/${entity.appId}/\${entityId}/data-query\`, params)
313
- return {
314
- items: (data.items ?? []).map(mapRow),
315
- total: data.total,
316
- }
317
- },
318
- }
319
- }
320
- `
321
- }
322
-
323
- function emitClient(entities: ArcubaseEntity[]): string {
324
- const imports = entities.map((entity) => {
325
- const typeName = toPascalCase(entity.sdkName)
326
- return `import { create${typeName}SDK } from './entities/${entity.sdkName}.js'`
327
- })
328
- const properties = entities.map((entity) => ` ${entity.sdkName}: create${toPascalCase(entity.sdkName)}SDK(runtime),`)
329
- return `import { createRuntime, type ArcubaseSdkConfig } from './runtime.js'
330
- ${imports.join('\n')}
331
-
332
- export function createArcubaseSdk(config: ArcubaseSdkConfig) {
333
- const runtime = createRuntime(config)
334
- return {
335
- ${properties.join('\n')}
336
- }
337
- }
338
- `
339
- }
7
+ import { CLIError } from './errors.js'
340
8
 
341
- function emitIndex(entities: ArcubaseEntity[]): string {
342
- return `export { createArcubaseSdk } from './client.js'
343
- export type { ArcubaseSdkConfig, ArcubaseRow } from './runtime.js'
344
- export { arcubaseSchema } from './schema.js'
345
- ${entities.map((entity) => `export type { ${toPascalCase(entity.sdkName)}Fields, ${toPascalCase(entity.sdkName)}CreateInput, ${toPascalCase(entity.sdkName)}UpdateInput } from './entities/${entity.sdkName}.js'`).join('\n')}
346
- `
347
- }
9
+ export type { GeneratedSDK, GeneratedSDKFile } from '@arcubase/code-gen'
348
10
 
349
11
  export function generateArcubaseProjectSDK(payload: unknown): GeneratedSDK {
350
- const entities = normalizeEntities(payload)
351
- return {
352
- files: [
353
- { path: 'runtime.ts', contents: emitRuntime() },
354
- { path: 'schema.ts', contents: emitSchema(entities) },
355
- ...entities.map((entity) => ({ path: `entities/${entity.sdkName}.ts`, contents: emitEntity(entity) })),
356
- { path: 'client.ts', contents: emitClient(entities) },
357
- { path: 'index.ts', contents: emitIndex(entities) },
358
- ],
12
+ try {
13
+ return generateArcubaseProjectSDKCore(payload)
14
+ } catch (error) {
15
+ if (error instanceof ArcubaseCodeGenError) {
16
+ throw new CLIError(error.code, error.message, 2)
17
+ }
18
+ throw error
359
19
  }
360
20
  }
@@ -295,7 +295,7 @@ function renderDevSDKGenHelp(): string {
295
295
  ' - arcubase-admin dev sdk-gen --app-id <app_id> --out src/arcubase',
296
296
  '',
297
297
  'requirements:',
298
- ' - missing field.key values are initialized through admin auth as field<id>',
298
+ ' - every generated field must have a configured field.key; sdk-gen fails fast when keys are missing',
299
299
  ' - existing field.key values must be stable unique TypeScript identifiers',
300
300
  ' - entity property names use entity.key when available, otherwise a stable entity<id> fallback',
301
301
  ' - generated code accepts createArcubaseSdk({ baseURL, accessToken, refreshToken })',
@@ -2006,11 +2006,6 @@ type SDKGenEntityRef = {
2006
2006
  id: string
2007
2007
  }
2008
2008
 
2009
- type SDKGenInitializedFieldKeys = {
2010
- entityId: number
2011
- fields: string[]
2012
- }
2013
-
2014
2009
  function extractSDKGenAppPayload(payload: unknown): Record<string, any> {
2015
2010
  const appPayload = unwrapResponseData(payload)
2016
2011
  if (!isRecord(appPayload)) {
@@ -2056,47 +2051,38 @@ function walkSDKGenFields(fields: unknown, visit: (field: Record<string, any>) =
2056
2051
  }
2057
2052
  }
2058
2053
 
2059
- function collectExistingSDKGenFieldKeys(entity: Record<string, any>): Set<string> {
2060
- const keys = new Set<string>()
2061
- walkSDKGenFields(entity.fields, (field) => {
2062
- if (typeof field.key === 'string' && field.key.trim() !== '') {
2063
- keys.add(field.key.trim())
2064
- }
2065
- })
2066
- return keys
2067
- }
2068
-
2069
- function nextSDKGenFallbackFieldKey(fieldId: number, usedKeys: Set<string>): string {
2070
- const base = `field${fieldId}`
2071
- if (!usedKeys.has(base)) {
2072
- usedKeys.add(base)
2073
- return base
2074
- }
2075
- let index = 2
2076
- while (usedKeys.has(`${base}_${index}`)) {
2077
- index++
2078
- }
2079
- const key = `${base}_${index}`
2080
- usedKeys.add(key)
2081
- return key
2082
- }
2083
-
2084
- function initializeMissingSDKGenFieldKeys(entity: Record<string, any>): Array<{ id: number; key: string }> {
2085
- const usedKeys = collectExistingSDKGenFieldKeys(entity)
2086
- const updates: Array<{ id: number; key: string }> = []
2054
+ function assertSDKGenFieldKeysPresent(entity: Record<string, any>) {
2055
+ const missing: Array<{ id: number; label: string }> = []
2087
2056
  walkSDKGenFields(entity.fields, (field) => {
2088
2057
  if (typeof field.id !== 'number') {
2089
2058
  return
2090
2059
  }
2091
2060
  if (typeof field.key === 'string' && field.key.trim() !== '') {
2092
- field.key = field.key.trim()
2093
2061
  return
2094
2062
  }
2095
- const key = nextSDKGenFallbackFieldKey(field.id, usedKeys)
2096
- field.key = key
2097
- updates.push({ id: field.id, key })
2063
+ missing.push({
2064
+ id: field.id,
2065
+ label: typeof field.label === 'string' && field.label.trim() ? field.label.trim() : `field ${field.id}`,
2066
+ })
2067
+ })
2068
+ if (missing.length === 0) {
2069
+ return
2070
+ }
2071
+
2072
+ const entityName = typeof entity.name === 'string' && entity.name.trim() ? entity.name.trim() : `entity ${String(entity.id ?? '')}`.trim()
2073
+ const preview = missing.slice(0, 8).map((field) => `${entityName}.${field.label} (${field.id})`)
2074
+ const suffix = missing.length > preview.length ? `, and ${missing.length - preview.length} more` : ''
2075
+ throw new CLIError('SDK_GEN_FIELD_KEY_REQUIRED', `missing field.key values: ${preview.join(', ')}${suffix}`, 2, {
2076
+ operation: 'dev sdk-gen',
2077
+ issues: missing.map((field) => ({
2078
+ path: `entity.${String(entity.id ?? 'unknown')}.field.${field.id}.key`,
2079
+ message: `field.key is required for ${entityName}.${field.label}`,
2080
+ })),
2081
+ suggestions: [
2082
+ 'set stable field.key values in Arcubase admin before running sdk-gen',
2083
+ 'rerun arcubase-admin dev sdk-gen after the schema keys are complete',
2084
+ ],
2098
2085
  })
2099
- return updates
2100
2086
  }
2101
2087
 
2102
2088
  async function executeDevSDKGen(
@@ -2131,7 +2117,6 @@ async function executeDevSDKGen(
2131
2117
  throw new CLIError('SDK_GEN_NO_ENTITIES', 'sdk-gen could not find entities in app detail response', 2)
2132
2118
  }
2133
2119
  const entities = []
2134
- const initializedFieldKeys: SDKGenInitializedFieldKeys[] = []
2135
2120
  for (const entityRef of entityRefs) {
2136
2121
  const entityEndpoint = `/api/apps/${encodeURIComponent(appId)}/entity/${encodeURIComponent(entityRef.id)}`
2137
2122
  const entityDetail = await requestJSON(runtimeEnv, 'GET', entityEndpoint, undefined, fetchImpl)
@@ -2139,15 +2124,7 @@ async function executeDevSDKGen(
2139
2124
  if (!isRecord(entityPayload)) {
2140
2125
  throw new CLIError('SDK_GEN_INVALID_SCHEMA', 'sdk-gen expected entity detail response data', 2)
2141
2126
  }
2142
- const customKeyUpdates = initializeMissingSDKGenFieldKeys(entityPayload)
2143
- if (customKeyUpdates.length > 0) {
2144
- const customKeysEndpoint = `/api/apps/${encodeURIComponent(appId)}/entity/${encodeURIComponent(entityRef.id)}/custom-keys`
2145
- await requestJSON(runtimeEnv, 'PUT', customKeysEndpoint, customKeyUpdates, fetchImpl)
2146
- initializedFieldKeys.push({
2147
- entityId: typeof entityPayload.id === 'number' ? entityPayload.id : Number(entityRef.id),
2148
- fields: customKeyUpdates.map((item) => item.key),
2149
- })
2150
- }
2127
+ assertSDKGenFieldKeysPresent(entityPayload)
2151
2128
  entities.push(entityPayload)
2152
2129
  }
2153
2130
  const generated = generateArcubaseProjectSDK({
@@ -2173,7 +2150,6 @@ async function executeDevSDKGen(
2173
2150
  data: {
2174
2151
  out: absoluteOutDir,
2175
2152
  files: generated.files.map((file) => file.path),
2176
- initializedFieldKeys,
2177
2153
  },
2178
2154
  }
2179
2155
  }
@@ -177,24 +177,16 @@ test('arcubase-admin dev sdk-gen fetches app schema and writes typed sdk files',
177
177
  assert.match(fs.readFileSync(path.join(outDir, 'client.ts'), 'utf8'), /createArcubaseSdk/)
178
178
  })
179
179
 
180
- test('arcubase-admin dev sdk-gen initializes missing field keys through admin auth before generation', async () => {
180
+ test('arcubase-admin dev sdk-gen fails before generation when field keys are missing', async () => {
181
181
  const outDir = fs.mkdtempSync(path.join(os.tmpdir(), 'arcubase-sdk-gen-'))
182
- const calls: Array<{ url: string; method?: string; authorization?: string; body?: any }> = []
182
+ const calls: Array<{ url: string; method?: string }> = []
183
183
 
184
- const result = await executeCLI(
184
+ await assert.rejects(() => executeCLI(
185
185
  'admin',
186
186
  ['dev', 'sdk-gen', '--app-id', '3882856425', '--out', outDir],
187
187
  env as any,
188
188
  async (url, init) => {
189
- const bodyText = typeof init?.body === 'string' ? init.body : undefined
190
- calls.push({
191
- url: String(url),
192
- method: init?.method,
193
- authorization: init?.headers instanceof Headers
194
- ? init.headers.get('Authorization') ?? undefined
195
- : (init?.headers as Record<string, string> | undefined)?.Authorization,
196
- body: bodyText ? JSON.parse(bodyText) : undefined,
197
- })
189
+ calls.push({ url: String(url), method: init?.method })
198
190
  if (String(url).endsWith('/api/apps/3882856425')) {
199
191
  return new Response(JSON.stringify({ data: appDetail() }), { status: 200 })
200
192
  }
@@ -204,23 +196,15 @@ test('arcubase-admin dev sdk-gen initializes missing field keys through admin au
204
196
  if (String(url).endsWith('/api/apps/3882856425/entity/3883547182')) {
205
197
  return new Response(JSON.stringify({ data: entityDetailWithoutFieldKeys() }), { status: 200 })
206
198
  }
207
- if (String(url).endsWith('/api/apps/3882856425/entity/3883547182/custom-keys')) {
208
- return new Response(JSON.stringify({ data: entityDetail() }), { status: 200 })
209
- }
210
199
  return new Response(JSON.stringify({ error: { message: `unexpected url ${url}` } }), { status: 404 })
211
200
  },
212
- )
201
+ ), (error: unknown) => {
202
+ assert.ok(error instanceof CLIError)
203
+ assert.equal(error.code, 'SDK_GEN_FIELD_KEY_REQUIRED')
204
+ assert.match(error.message, /编故事\.时代 \(1006\)/)
205
+ return true
206
+ })
213
207
 
214
- assert.equal(result.kind, 'result')
215
- const customKeysCall = calls.find((call) => call.url.endsWith('/api/apps/3882856425/entity/3883547182/custom-keys'))
216
- assert.ok(customKeysCall)
217
- assert.equal(customKeysCall.method, 'PUT')
218
- assert.equal(customKeysCall.authorization, 'Bearer tok')
219
- assert.deepEqual(customKeysCall.body, [
220
- { id: 1006, key: 'field1006' },
221
- { id: 1013, key: 'field1013' },
222
- { id: 1011, key: 'field1011' },
223
- ])
224
- assert.match(fs.readFileSync(path.join(outDir, 'entities/story.ts'), 'utf8'), /field1011: string/)
225
- assert.deepEqual(result.data.initializedFieldKeys, [{ entityId: 3883547182, fields: ['field1006', 'field1013', 'field1011'] }])
208
+ assert.equal(calls.some((call) => call.url.endsWith('/custom-keys')), false)
209
+ assert.equal(fs.existsSync(path.join(outDir, 'index.ts')), false)
226
210
  })