@tinacms/cli 1.9.4 → 1.9.5

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/dist/index.js CHANGED
@@ -35,24 +35,16 @@ module.exports = __toCommonJS(index_exports);
35
35
  var import_clipanion8 = require("clipanion");
36
36
 
37
37
  // package.json
38
- var version = "1.9.4";
38
+ var version = "1.9.5";
39
39
 
40
40
  // src/next/commands/dev-command/index.ts
41
+ var import_path5 = __toESM(require("path"));
42
+ var import_graphql10 = require("@tinacms/graphql");
43
+ var import_search = require("@tinacms/search");
41
44
  var import_async_lock = __toESM(require("async-lock"));
45
+ var import_chokidar = __toESM(require("chokidar"));
42
46
  var import_clipanion2 = require("clipanion");
43
47
  var import_fs_extra6 = __toESM(require("fs-extra"));
44
- var import_path5 = __toESM(require("path"));
45
- var import_chokidar = __toESM(require("chokidar"));
46
- var import_graphql10 = require("@tinacms/graphql");
47
-
48
- // src/next/config-manager.ts
49
- var import_fs_extra = __toESM(require("fs-extra"));
50
- var import_path = __toESM(require("path"));
51
- var import_os = __toESM(require("os"));
52
- var esbuild = __toESM(require("esbuild"));
53
- var dotenv = __toESM(require("dotenv"));
54
- var import_normalize_path = __toESM(require("normalize-path"));
55
- var import_chalk2 = __toESM(require("chalk"));
56
48
 
57
49
  // src/logger/index.ts
58
50
  var import_chalk = __toESM(require("chalk"));
@@ -165,2170 +157,2176 @@ var S_SUCCESS = s("\u25C6", "*");
165
157
  var S_WARN = s("\u25B2", "!");
166
158
  var S_ERROR = s("\u25A0", "x");
167
159
 
168
- // src/next/config-manager.ts
169
- var TINA_FOLDER = "tina";
170
- var LEGACY_TINA_FOLDER = ".tina";
171
- var GENERATED_FOLDER = "__generated__";
172
- var GRAPHQL_JSON_FILE = "_graphql.json";
173
- var GRAPHQL_GQL_FILE = "schema.gql";
174
- var SCHEMA_JSON_FILE = "_schema.json";
175
- var LOOKUP_JSON_FILE = "_lookup.json";
176
- var ConfigManager = class {
177
- constructor({
178
- rootPath = process.cwd(),
179
- tinaGraphQLVersion,
180
- legacyNoSDK
181
- }) {
182
- this.rootPath = (0, import_normalize_path.default)(rootPath);
183
- this.tinaGraphQLVersionFromCLI = tinaGraphQLVersion;
184
- this.legacyNoSDK = legacyNoSDK;
185
- }
186
- isUsingTs() {
187
- return [".ts", ".tsx"].includes(import_path.default.extname(this.tinaConfigFilePath));
188
- }
189
- hasSelfHostedConfig() {
190
- return !!this.selfHostedDatabaseFilePath;
160
+ // src/utils/spinner.ts
161
+ var import_cli_spinner = require("cli-spinner");
162
+ async function localSpin({
163
+ waitFor,
164
+ text
165
+ }) {
166
+ const spinner = new import_cli_spinner.Spinner({
167
+ text: `${text} %s`,
168
+ stream: process.stderr,
169
+ onTick: function(msg) {
170
+ this.clearLine(this.stream);
171
+ this.stream.write(msg);
172
+ }
173
+ });
174
+ spinner.setSpinnerString("\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827\u2807\u280F");
175
+ spinner.start();
176
+ const res = await waitFor();
177
+ spinner.stop();
178
+ console.log("");
179
+ return res;
180
+ }
181
+ function spin({
182
+ waitFor,
183
+ text
184
+ }) {
185
+ if (process.env.CI) {
186
+ console.log(text);
187
+ return waitFor();
188
+ } else {
189
+ return localSpin({
190
+ text,
191
+ waitFor
192
+ });
191
193
  }
192
- hasSeparateContentRoot() {
193
- return this.rootPath !== this.contentRootPath;
194
+ }
195
+
196
+ // src/utils/theme.ts
197
+ var import_chalk2 = __toESM(require("chalk"));
198
+ var successText = import_chalk2.default.bold.green;
199
+ var focusText = import_chalk2.default.bold;
200
+ var dangerText = import_chalk2.default.bold.red;
201
+ var neutralText = import_chalk2.default.bold.cyan;
202
+ var linkText = import_chalk2.default.bold.cyan;
203
+ var labelText = import_chalk2.default.bold;
204
+ var cmdText = import_chalk2.default.inverse;
205
+ var indentedCmd = (str) => {
206
+ return ` \u2503 ` + str;
207
+ };
208
+ var indentText = (str) => {
209
+ return String(str).split("\n").map((line) => ` ${line}`).join("\n");
210
+ };
211
+ var logText = import_chalk2.default.italic.gray;
212
+ var warnText = import_chalk2.default.yellowBright.bgBlack;
213
+ var titleText = import_chalk2.default.bgHex("d2f1f8").hex("ec4816");
214
+ var CONFIRMATION_TEXT = import_chalk2.default.dim("enter to confirm");
215
+
216
+ // src/next/codegen/index.ts
217
+ var import_fs_extra = __toESM(require("fs-extra"));
218
+ var import_path = __toESM(require("path"));
219
+ var import_graphql5 = require("graphql");
220
+
221
+ // src/next/codegen/codegen/index.ts
222
+ var import_graphql4 = require("graphql");
223
+
224
+ // src/next/codegen/codegen/plugin.ts
225
+ var AddGeneratedClientFunc = (apiURL) => {
226
+ return (_schema, _documents, _config, _info) => {
227
+ return `
228
+ // TinaSDK generated code
229
+ import { createClient, TinaClient } from "tinacms/dist/client";
230
+
231
+ const generateRequester = (
232
+ client: TinaClient,
233
+ ) => {
234
+ const requester: (
235
+ doc: any,
236
+ vars?: any,
237
+ options?: {
238
+ branch?: string,
239
+ /**
240
+ * Aside from \`method\` and \`body\`, all fetch options are passed
241
+ * through to underlying fetch request
242
+ */
243
+ fetchOptions?: Omit<Parameters<typeof fetch>[1], 'body' | 'method'>,
244
+ },
245
+ client
246
+ ) => Promise<any> = async (doc, vars, options) => {
247
+ let url = client.apiUrl
248
+ if (options?.branch) {
249
+ const index = client.apiUrl.lastIndexOf('/')
250
+ url = client.apiUrl.substring(0, index + 1) + options.branch
251
+ }
252
+ const data = await client.request({
253
+ query: doc,
254
+ variables: vars,
255
+ url,
256
+ }, options)
257
+
258
+ return { data: data?.data, errors: data?.errors, query: doc, variables: vars || {} }
194
259
  }
195
- shouldSkipSDK() {
196
- var _a;
197
- if (this.legacyNoSDK) {
198
- return this.legacyNoSDK;
260
+
261
+ return requester
262
+ }
263
+
264
+ /**
265
+ * @experimental this class can be used but may change in the future
266
+ **/
267
+ export const ExperimentalGetTinaClient = () =>
268
+ getSdk(
269
+ generateRequester(
270
+ createClient({
271
+ url: "${apiURL}",
272
+ queries,
273
+ })
274
+ )
275
+ )
276
+
277
+ export const queries = (
278
+ client: TinaClient,
279
+ ) => {
280
+ const requester = generateRequester(client)
281
+ return getSdk(requester)
282
+ }
283
+ `;
284
+ };
285
+ };
286
+ var AddGeneratedClient = (apiURL) => ({
287
+ plugin: AddGeneratedClientFunc(apiURL)
288
+ });
289
+
290
+ // src/next/codegen/codegen/index.ts
291
+ var import_graphql_file_loader = require("@graphql-tools/graphql-file-loader");
292
+ var import_core = require("@graphql-codegen/core");
293
+ var import_load = require("@graphql-tools/load");
294
+ var import_typescript_operations = require("@graphql-codegen/typescript-operations");
295
+ var import_typescript = require("@graphql-codegen/typescript");
296
+
297
+ // src/next/codegen/codegen/sdkPlugin/index.ts
298
+ var import_graphql2 = require("graphql");
299
+ var import_graphql3 = require("graphql");
300
+
301
+ // src/next/codegen/codegen/sdkPlugin/visitor.ts
302
+ var import_visitor_plugin_common = require("@graphql-codegen/visitor-plugin-common");
303
+ var import_auto_bind = __toESM(require("auto-bind"));
304
+ var import_graphql = require("graphql");
305
+ var GenericSdkVisitor = class extends import_visitor_plugin_common.ClientSideBaseVisitor {
306
+ constructor(schema, fragments, rawConfig) {
307
+ super(schema, fragments, rawConfig, {
308
+ usingObservableFrom: rawConfig.usingObservableFrom
309
+ });
310
+ this._operationsToInclude = [];
311
+ (0, import_auto_bind.default)(this);
312
+ if (this.config.usingObservableFrom) {
313
+ this._additionalImports.push(this.config.usingObservableFrom);
314
+ }
315
+ if (this.config.documentMode !== import_visitor_plugin_common.DocumentMode.string) {
199
316
  }
200
- return ((_a = this.config.client) == null ? void 0 : _a.skip) || false;
201
317
  }
202
- async processConfig() {
203
- this.tinaFolderPath = await this.getTinaFolderPath(this.rootPath);
204
- this.envFilePath = import_path.default.resolve(
205
- import_path.default.join(this.tinaFolderPath, "..", ".env")
206
- );
207
- dotenv.config({ path: this.envFilePath });
208
- this.tinaConfigFilePath = await this.getPathWithExtension(
209
- import_path.default.join(this.tinaFolderPath, "config")
210
- );
211
- if (!this.tinaConfigFilePath) {
318
+ buildOperation(node, documentVariableName, operationType, operationResultType, operationVariablesTypes) {
319
+ if (node.name == null) {
212
320
  throw new Error(
213
- `Unable to find config file in ${this.tinaFolderPath}. Looking for a file named "config.{ts,tsx,js,jsx}"`
321
+ "Plugin 'generic-sdk' cannot generate SDK for unnamed operation.\n\n" + (0, import_graphql.print)(node)
214
322
  );
323
+ } else {
324
+ this._operationsToInclude.push({
325
+ node,
326
+ documentVariableName,
327
+ operationType,
328
+ // This is the only line that is different
329
+ operationResultType: `{data: ${operationResultType}, errors?: { message: string, locations: { line: number, column: number }[], path: string[] }[], variables: ${operationVariablesTypes}, query: string}`,
330
+ operationVariablesTypes
331
+ });
215
332
  }
216
- this.selfHostedDatabaseFilePath = await this.getPathWithExtension(
217
- import_path.default.join(this.tinaFolderPath, "database")
218
- );
219
- this.generatedFolderPath = import_path.default.join(this.tinaFolderPath, GENERATED_FOLDER);
220
- this.generatedCachePath = import_path.default.join(
221
- this.generatedFolderPath,
222
- ".cache",
223
- String((/* @__PURE__ */ new Date()).getTime())
224
- );
225
- this.generatedGraphQLGQLPath = import_path.default.join(
226
- this.generatedFolderPath,
227
- GRAPHQL_GQL_FILE
228
- );
229
- this.generatedGraphQLJSONPath = import_path.default.join(
230
- this.generatedFolderPath,
231
- GRAPHQL_JSON_FILE
232
- );
233
- this.generatedSchemaJSONPath = import_path.default.join(
234
- this.generatedFolderPath,
235
- SCHEMA_JSON_FILE
236
- );
237
- this.generatedLookupJSONPath = import_path.default.join(
238
- this.generatedFolderPath,
239
- LOOKUP_JSON_FILE
240
- );
241
- this.generatedQueriesFilePath = import_path.default.join(
242
- this.generatedFolderPath,
243
- "queries.gql"
244
- );
245
- this.generatedFragmentsFilePath = import_path.default.join(
246
- this.generatedFolderPath,
247
- "frags.gql"
248
- );
249
- this.generatedTypesTSFilePath = import_path.default.join(
250
- this.generatedFolderPath,
251
- "types.ts"
252
- );
253
- this.generatedTypesJSFilePath = import_path.default.join(
254
- this.generatedFolderPath,
255
- "types.js"
256
- );
257
- this.generatedTypesDFilePath = import_path.default.join(
258
- this.generatedFolderPath,
259
- "types.d.ts"
260
- );
261
- this.userQueriesAndFragmentsGlob = import_path.default.join(
262
- this.tinaFolderPath,
263
- "queries/**/*.{graphql,gql}"
264
- );
265
- this.generatedQueriesAndFragmentsGlob = import_path.default.join(
266
- this.generatedFolderPath,
267
- "*.{graphql,gql}"
268
- );
269
- this.generatedClientTSFilePath = import_path.default.join(
270
- this.generatedFolderPath,
271
- "client.ts"
272
- );
273
- this.generatedClientJSFilePath = import_path.default.join(
274
- this.generatedFolderPath,
275
- "client.js"
276
- );
277
- this.generatedClientDFilePath = import_path.default.join(
278
- this.generatedFolderPath,
279
- "client.d.ts"
280
- );
281
- this.generatedDatabaseClientDFilePath = import_path.default.join(
282
- this.generatedFolderPath,
283
- "databaseClient.d.ts"
284
- );
285
- this.generatedDatabaseClientTSFilePath = import_path.default.join(
286
- this.generatedFolderPath,
287
- "databaseClient.ts"
288
- );
289
- this.generatedDatabaseClientJSFilePath = import_path.default.join(
290
- this.generatedFolderPath,
291
- "databaseClient.js"
292
- );
293
- const clientExists = this.isUsingTs() ? await import_fs_extra.default.pathExists(this.generatedClientTSFilePath) : await import_fs_extra.default.pathExists(this.generatedClientJSFilePath);
294
- if (!clientExists) {
295
- const file = "export default ()=>({})\nexport const client = ()=>({})";
296
- if (this.isUsingTs()) {
297
- await import_fs_extra.default.outputFile(this.generatedClientTSFilePath, file);
298
- } else {
299
- await import_fs_extra.default.outputFile(this.generatedClientJSFilePath, file);
300
- }
301
- }
302
- const { config: config2, prebuildPath, watchList } = await this.loadConfigFile(
303
- this.generatedFolderPath,
304
- this.tinaConfigFilePath
305
- );
306
- this.watchList = watchList;
307
- this.config = config2;
308
- this.prebuildFilePath = prebuildPath;
309
- this.publicFolderPath = import_path.default.join(
310
- this.rootPath,
311
- this.config.build.publicFolder
312
- );
313
- this.outputFolderPath = import_path.default.join(
314
- this.publicFolderPath,
315
- this.config.build.outputFolder
316
- );
317
- this.outputHTMLFilePath = import_path.default.join(this.outputFolderPath, "index.html");
318
- this.outputGitignorePath = import_path.default.join(this.outputFolderPath, ".gitignore");
319
- const fullLocalContentPath = import_path.default.join(
320
- this.tinaFolderPath,
321
- this.config.localContentPath || ""
322
- );
323
- if (this.config.localContentPath) {
324
- const localContentPathExists = await import_fs_extra.default.pathExists(fullLocalContentPath);
325
- if (localContentPathExists) {
326
- logger.info(`Using separate content repo at ${fullLocalContentPath}`);
327
- this.contentRootPath = fullLocalContentPath;
328
- } else {
329
- logger.warn(
330
- `${import_chalk2.default.yellow("Warning:")} The localContentPath ${import_chalk2.default.cyan(
331
- fullLocalContentPath
332
- )} does not exist. Please create it or remove the localContentPath from your config file at ${import_chalk2.default.cyan(
333
- this.tinaConfigFilePath
334
- )}`
335
- );
336
- }
337
- }
338
- if (!this.contentRootPath) {
339
- this.contentRootPath = this.rootPath;
340
- }
341
- this.generatedFolderPathContentRepo = import_path.default.join(
342
- await this.getTinaFolderPath(this.contentRootPath),
343
- GENERATED_FOLDER
344
- );
345
- this.spaMainPath = require.resolve("@tinacms/app");
346
- this.spaRootPath = import_path.default.join(this.spaMainPath, "..", "..");
347
- }
348
- async getTinaFolderPath(rootPath) {
349
- const tinaFolderPath = import_path.default.join(rootPath, TINA_FOLDER);
350
- const tinaFolderExists = await import_fs_extra.default.pathExists(tinaFolderPath);
351
- if (tinaFolderExists) {
352
- this.isUsingLegacyFolder = false;
353
- return tinaFolderPath;
354
- }
355
- const legacyFolderPath = import_path.default.join(rootPath, LEGACY_TINA_FOLDER);
356
- const legacyFolderExists = await import_fs_extra.default.pathExists(legacyFolderPath);
357
- if (legacyFolderExists) {
358
- this.isUsingLegacyFolder = true;
359
- return legacyFolderPath;
360
- }
361
- throw new Error(
362
- `Unable to find Tina folder, if you're working in folder outside of the Tina config be sure to specify --rootPath`
363
- );
333
+ return null;
364
334
  }
365
- getTinaGraphQLVersion() {
366
- if (this.tinaGraphQLVersionFromCLI) {
367
- const version2 = this.tinaGraphQLVersionFromCLI.split(".");
368
- return {
369
- fullVersion: this.tinaGraphQLVersionFromCLI,
370
- major: version2[0] || "x",
371
- minor: version2[1] || "x",
372
- patch: version2[2] || "x"
373
- };
374
- }
375
- const generatedSchema = import_fs_extra.default.readJSONSync(this.generatedSchemaJSONPath);
376
- if (!generatedSchema || !(typeof (generatedSchema == null ? void 0 : generatedSchema.version) !== "undefined")) {
377
- throw new Error(
378
- `Can not find Tina GraphQL version in ${this.generatedSchemaJSONPath}`
335
+ get sdkContent() {
336
+ const usingObservable = !!this.config.usingObservableFrom;
337
+ const allPossibleActions = this._operationsToInclude.map((o) => {
338
+ const optionalVariables = !o.node.variableDefinitions || o.node.variableDefinitions.length === 0 || o.node.variableDefinitions.every(
339
+ (v) => v.type.kind !== import_graphql.Kind.NON_NULL_TYPE || v.defaultValue
379
340
  );
380
- }
381
- return generatedSchema.version;
382
- }
383
- printGeneratedClientFilePath() {
384
- if (this.isUsingTs()) {
385
- return this.generatedClientTSFilePath.replace(`${this.rootPath}/`, "");
386
- }
387
- return this.generatedClientJSFilePath.replace(`${this.rootPath}/`, "");
388
- }
389
- printGeneratedTypesFilePath() {
390
- return this.generatedTypesTSFilePath.replace(`${this.rootPath}/`, "");
341
+ const returnType = usingObservable && o.operationType === "Subscription" ? "Observable" : "Promise";
342
+ return `${o.node.name.value}(variables${optionalVariables ? "?" : ""}: ${o.operationVariablesTypes}, options?: C): ${returnType}<${o.operationResultType}> {
343
+ return requester<${o.operationResultType}, ${o.operationVariablesTypes}>(${o.documentVariableName}, variables, options);
344
+ }`;
345
+ }).map((s2) => (0, import_visitor_plugin_common.indentMultiline)(s2, 2));
346
+ return `export type Requester<C= {}> = <R, V>(doc: ${this.config.documentMode === import_visitor_plugin_common.DocumentMode.string ? "string" : "DocumentNode"}, vars?: V, options?: C) => ${usingObservable ? "Promise<R> & Observable<R>" : "Promise<R>"}
347
+ export function getSdk<C>(requester: Requester<C>) {
348
+ return {
349
+ ${allPossibleActions.join(",\n")}
350
+ };
391
351
  }
392
- printoutputHTMLFilePath() {
393
- return this.outputHTMLFilePath.replace(`${this.publicFolderPath}/`, "");
352
+ export type Sdk = ReturnType<typeof getSdk>;`;
394
353
  }
395
- printRelativePath(filename) {
396
- if (filename) {
397
- return filename.replace(/\\/g, "/").replace(`${this.rootPath}/`, "");
354
+ };
355
+
356
+ // src/next/codegen/codegen/sdkPlugin/index.ts
357
+ var plugin = (schema, documents, config2) => {
358
+ const allAst = (0, import_graphql3.concatAST)(
359
+ documents.reduce((prev, v) => {
360
+ return [...prev, v.document];
361
+ }, [])
362
+ );
363
+ const allFragments = [
364
+ ...allAst.definitions.filter(
365
+ (d) => d.kind === import_graphql3.Kind.FRAGMENT_DEFINITION
366
+ ).map((fragmentDef) => ({
367
+ node: fragmentDef,
368
+ name: fragmentDef.name.value,
369
+ onType: fragmentDef.typeCondition.name.value,
370
+ isExternal: false
371
+ })),
372
+ ...config2.externalFragments || []
373
+ ];
374
+ const visitor = new GenericSdkVisitor(schema, allFragments, config2);
375
+ const visitorResult = (0, import_graphql2.visit)(allAst, { leave: visitor });
376
+ return {
377
+ // We will take care of imports
378
+ // prepend: visitor.getImports(),
379
+ content: [
380
+ visitor.fragments,
381
+ ...visitorResult.definitions.filter((t) => typeof t === "string"),
382
+ visitor.sdkContent
383
+ ].join("\n")
384
+ };
385
+ };
386
+
387
+ // src/next/codegen/codegen/index.ts
388
+ var generateTypes = async (schema, queryPathGlob = process.cwd(), fragDocPath = process.cwd(), apiURL) => {
389
+ let docs = [];
390
+ let fragDocs = [];
391
+ docs = await loadGraphQLDocuments(queryPathGlob);
392
+ fragDocs = await loadGraphQLDocuments(fragDocPath);
393
+ const res = await (0, import_core.codegen)({
394
+ // Filename is not used. This is because the typescript plugin returns a string instead of writing to a file.
395
+ filename: process.cwd(),
396
+ schema: (0, import_graphql4.parse)((0, import_graphql4.printSchema)(schema)),
397
+ documents: [...docs, ...fragDocs],
398
+ config: {},
399
+ plugins: [
400
+ { typescript: {} },
401
+ { typescriptOperations: {} },
402
+ {
403
+ typescriptSdk: {}
404
+ },
405
+ { AddGeneratedClient: {} }
406
+ ],
407
+ pluginMap: {
408
+ typescript: {
409
+ plugin: import_typescript.plugin
410
+ },
411
+ typescriptOperations: {
412
+ plugin: import_typescript_operations.plugin
413
+ },
414
+ typescriptSdk: {
415
+ plugin
416
+ },
417
+ AddGeneratedClient: AddGeneratedClient(apiURL)
418
+ }
419
+ });
420
+ return res;
421
+ };
422
+ var loadGraphQLDocuments = async (globPath) => {
423
+ let result = [];
424
+ try {
425
+ result = await (0, import_load.loadDocuments)(globPath, {
426
+ loaders: [new import_graphql_file_loader.GraphQLFileLoader()]
427
+ });
428
+ } catch (e) {
429
+ if (
430
+ // https://www.graphql-tools.com/docs/documents-loading#no-files-found
431
+ (e.message || "").includes(
432
+ "Unable to find any GraphQL type definitions for the following pointers:"
433
+ )
434
+ ) {
435
+ } else {
436
+ throw e;
398
437
  }
399
- throw `No path provided to print`;
400
438
  }
401
- printPrebuildFilePath() {
402
- return this.prebuildFilePath.replace(/\\/g, "/").replace(`${this.rootPath}/${this.tinaFolderPath}/`, "");
439
+ return result;
440
+ };
441
+
442
+ // src/next/codegen/index.ts
443
+ var import_esbuild = require("esbuild");
444
+ var import_graphql6 = require("@tinacms/graphql");
445
+ var import_normalize_path = __toESM(require("normalize-path"));
446
+ var TINA_HOST = "content.tinajs.io";
447
+ var Codegen = class {
448
+ constructor({
449
+ configManager,
450
+ port,
451
+ queryDoc,
452
+ fragDoc,
453
+ isLocal,
454
+ graphqlSchemaDoc,
455
+ tinaSchema,
456
+ lookup,
457
+ noClientBuildCache
458
+ }) {
459
+ this.isLocal = isLocal;
460
+ this.graphqlSchemaDoc = graphqlSchemaDoc;
461
+ this.configManager = configManager;
462
+ this.port = port;
463
+ this.schema = (0, import_graphql5.buildASTSchema)(graphqlSchemaDoc);
464
+ this.tinaSchema = tinaSchema;
465
+ this.queryDoc = queryDoc;
466
+ this.fragDoc = fragDoc;
467
+ this.lookup = lookup;
468
+ this.noClientBuildCache = noClientBuildCache;
403
469
  }
404
- printContentRelativePath(filename) {
405
- if (filename) {
406
- return filename.replace(/\\/g, "/").replace(`${this.contentRootPath}/`, "");
470
+ async writeConfigFile(fileName, data) {
471
+ const filePath = import_path.default.join(
472
+ this.configManager.generatedFolderPath,
473
+ fileName
474
+ );
475
+ await import_fs_extra.default.ensureFile(filePath);
476
+ await import_fs_extra.default.outputFile(filePath, data);
477
+ if (this.configManager.hasSeparateContentRoot()) {
478
+ const filePath2 = import_path.default.join(
479
+ this.configManager.generatedFolderPathContentRepo,
480
+ fileName
481
+ );
482
+ await import_fs_extra.default.ensureFile(filePath2);
483
+ await import_fs_extra.default.outputFile(filePath2, data);
407
484
  }
408
- throw `No path provided to print`;
409
485
  }
410
- /**
411
- * Given a filepath without an extension, find the first match (eg. tsx, ts, jsx, js)
412
- */
413
- async getPathWithExtension(filepath) {
414
- const extensions = ["tsx", "ts", "jsx", "js"];
415
- let result;
416
- await Promise.all(
417
- extensions.map(async (ext) => {
418
- if (result) {
419
- return;
420
- }
421
- const filepathWithExtension = `${filepath}.${ext}`;
422
- const exists = import_fs_extra.default.existsSync(filepathWithExtension);
423
- if (exists) {
424
- result = filepathWithExtension;
425
- }
426
- })
427
- );
428
- return result;
486
+ async removeGeneratedFilesIfExists() {
487
+ await unlinkIfExists(this.configManager.generatedClientJSFilePath);
488
+ await unlinkIfExists(this.configManager.generatedTypesDFilePath);
489
+ await unlinkIfExists(this.configManager.generatedTypesJSFilePath);
490
+ await unlinkIfExists(this.configManager.generatedTypesTSFilePath);
491
+ await unlinkIfExists(this.configManager.generatedClientTSFilePath);
492
+ await unlinkIfExists(this.configManager.generatedQueriesFilePath);
493
+ await unlinkIfExists(this.configManager.generatedFragmentsFilePath);
429
494
  }
430
- async loadDatabaseFile() {
431
- const tmpdir = import_path.default.join(import_os.default.tmpdir(), Date.now().toString());
432
- const outfile = import_path.default.join(tmpdir, "database.build.js");
433
- await esbuild.build({
434
- entryPoints: [this.selfHostedDatabaseFilePath],
435
- bundle: true,
436
- platform: "node",
437
- outfile,
438
- loader: loaders
439
- });
440
- const result = require(outfile);
441
- import_fs_extra.default.removeSync(outfile);
442
- return result.default;
443
- }
444
- async loadConfigFile(generatedFolderPath, configFilePath) {
445
- const tmpdir = import_path.default.join(import_os.default.tmpdir(), Date.now().toString());
446
- const preBuildConfigPath = import_path.default.join(
447
- this.generatedFolderPath,
448
- "config.prebuild.jsx"
495
+ async execute() {
496
+ await this.writeConfigFile(
497
+ "_graphql.json",
498
+ JSON.stringify(this.graphqlSchemaDoc)
449
499
  );
450
- const outfile = import_path.default.join(tmpdir, "config.build.jsx");
451
- const outfile2 = import_path.default.join(tmpdir, "config.build.js");
452
- const tempTSConfigFile = import_path.default.join(tmpdir, "tsconfig.json");
453
- import_fs_extra.default.outputFileSync(tempTSConfigFile, "{}");
454
- const result2 = await esbuild.build({
455
- entryPoints: [configFilePath],
456
- bundle: true,
457
- target: ["es2020"],
458
- platform: "browser",
459
- format: "esm",
460
- logLevel: "silent",
461
- packages: "external",
462
- ignoreAnnotations: true,
463
- outfile: preBuildConfigPath,
464
- loader: loaders,
465
- metafile: true
466
- });
467
- const flattenedList = [];
468
- Object.keys(result2.metafile.inputs).forEach((key) => {
469
- if (key.includes("node_modules") || key.includes("__generated__")) {
470
- return;
500
+ const { search, ...rest } = this.tinaSchema.schema.config;
501
+ this.tinaSchema.schema.config = rest;
502
+ await this.writeConfigFile(
503
+ "_schema.json",
504
+ JSON.stringify(this.tinaSchema.schema)
505
+ );
506
+ await this.writeConfigFile("_lookup.json", JSON.stringify(this.lookup));
507
+ const { apiURL, localUrl, tinaCloudUrl } = this._createApiUrl();
508
+ this.apiURL = apiURL;
509
+ this.localUrl = localUrl;
510
+ this.productionUrl = tinaCloudUrl;
511
+ if (this.configManager.shouldSkipSDK()) {
512
+ await this.removeGeneratedFilesIfExists();
513
+ return apiURL;
514
+ }
515
+ await import_fs_extra.default.outputFile(
516
+ this.configManager.generatedQueriesFilePath,
517
+ this.queryDoc
518
+ );
519
+ await import_fs_extra.default.outputFile(
520
+ this.configManager.generatedFragmentsFilePath,
521
+ this.fragDoc
522
+ );
523
+ await maybeWarnFragmentSize(this.configManager.generatedFragmentsFilePath);
524
+ const { clientString } = await this.genClient();
525
+ const databaseClientString = this.configManager.hasSelfHostedConfig() ? await this.genDatabaseClient() : "";
526
+ const { codeString, schemaString } = await this.genTypes();
527
+ await import_fs_extra.default.outputFile(
528
+ this.configManager.generatedGraphQLGQLPath,
529
+ schemaString
530
+ );
531
+ if (this.configManager.isUsingTs()) {
532
+ await import_fs_extra.default.outputFile(
533
+ this.configManager.generatedTypesTSFilePath,
534
+ codeString
535
+ );
536
+ await import_fs_extra.default.outputFile(
537
+ this.configManager.generatedClientTSFilePath,
538
+ clientString
539
+ );
540
+ if (this.configManager.hasSelfHostedConfig()) {
541
+ await import_fs_extra.default.outputFile(
542
+ this.configManager.generatedDatabaseClientTSFilePath,
543
+ databaseClientString
544
+ );
545
+ }
546
+ await unlinkIfExists(this.configManager.generatedClientJSFilePath);
547
+ await unlinkIfExists(this.configManager.generatedTypesDFilePath);
548
+ await unlinkIfExists(this.configManager.generatedTypesJSFilePath);
549
+ } else {
550
+ await import_fs_extra.default.outputFile(
551
+ this.configManager.generatedTypesDFilePath,
552
+ codeString
553
+ );
554
+ const jsTypes = await (0, import_esbuild.transform)(codeString, { loader: "ts" });
555
+ await import_fs_extra.default.outputFile(
556
+ this.configManager.generatedTypesJSFilePath,
557
+ jsTypes.code
558
+ );
559
+ await import_fs_extra.default.outputFile(
560
+ this.configManager.generatedClientDFilePath,
561
+ clientString
562
+ );
563
+ const jsClient = await (0, import_esbuild.transform)(clientString, { loader: "ts" });
564
+ await import_fs_extra.default.outputFile(
565
+ this.configManager.generatedClientJSFilePath,
566
+ jsClient.code
567
+ );
568
+ await unlinkIfExists(this.configManager.generatedTypesTSFilePath);
569
+ await unlinkIfExists(this.configManager.generatedClientTSFilePath);
570
+ if (this.configManager.hasSelfHostedConfig()) {
571
+ const jsDatabaseClient = await (0, import_esbuild.transform)(databaseClientString, {
572
+ loader: "ts"
573
+ });
574
+ await import_fs_extra.default.outputFile(
575
+ this.configManager.generatedDatabaseClientJSFilePath,
576
+ jsDatabaseClient.code
577
+ );
578
+ await import_fs_extra.default.outputFile(
579
+ this.configManager.generatedDatabaseClientDFilePath,
580
+ databaseClientString
581
+ );
582
+ await unlinkIfExists(
583
+ this.configManager.generatedDatabaseClientTSFilePath
584
+ );
471
585
  }
472
- flattenedList.push(key);
473
- });
474
- await esbuild.build({
475
- entryPoints: [configFilePath],
476
- bundle: true,
477
- target: ["es2020"],
478
- logLevel: "silent",
479
- platform: "node",
480
- outfile,
481
- loader: loaders
482
- });
483
- await esbuild.build({
484
- entryPoints: [outfile],
485
- bundle: true,
486
- // Suppress warning about comparison with -0 from client module
487
- logLevel: "silent",
488
- platform: "node",
489
- outfile: outfile2,
490
- loader: loaders
491
- });
492
- let result;
493
- try {
494
- result = require(outfile2);
495
- } catch (e) {
496
- console.error("Unexpected error loading config");
497
- console.error(e);
498
- throw e;
499
586
  }
500
- import_fs_extra.default.removeSync(outfile);
501
- import_fs_extra.default.removeSync(outfile2);
502
- return {
503
- config: result.default,
504
- prebuildPath: preBuildConfigPath,
505
- watchList: flattenedList
506
- };
587
+ return apiURL;
507
588
  }
508
- };
509
- var loaders = {
510
- ".aac": "file",
511
- ".css": "file",
512
- ".eot": "file",
513
- ".flac": "file",
514
- ".gif": "file",
515
- ".jpeg": "file",
516
- ".jpg": "file",
517
- ".json": "json",
518
- ".mp3": "file",
519
- ".mp4": "file",
520
- ".ogg": "file",
521
- ".otf": "file",
522
- ".png": "file",
523
- ".svg": "file",
524
- ".ttf": "file",
525
- ".wav": "file",
526
- ".webm": "file",
527
- ".webp": "file",
528
- ".woff": "file",
529
- ".woff2": "file",
530
- ".js": "jsx",
531
- ".jsx": "jsx",
532
- ".tsx": "tsx"
533
- };
589
+ _createApiUrl() {
590
+ var _a, _b, _c, _d;
591
+ const branch = (_a = this.configManager.config) == null ? void 0 : _a.branch;
592
+ const clientId = (_b = this.configManager.config) == null ? void 0 : _b.clientId;
593
+ const token = (_c = this.configManager.config) == null ? void 0 : _c.token;
594
+ const fullVersion = this.configManager.getTinaGraphQLVersion();
595
+ const version2 = `${fullVersion.major}.${fullVersion.minor}`;
596
+ const baseUrl = ((_d = this.configManager.config.tinaioConfig) == null ? void 0 : _d.contentApiUrlOverride) || `https://${TINA_HOST}`;
597
+ if ((!branch || !clientId || !token) && !this.port && !this.configManager.config.contentApiUrlOverride) {
598
+ const missing = [];
599
+ if (!branch) missing.push("branch");
600
+ if (!clientId) missing.push("clientId");
601
+ if (!token) missing.push("token");
602
+ throw new Error(
603
+ `Client not configured properly. Missing ${missing.join(
604
+ ", "
605
+ )}. Please visit https://tina.io/docs/tina-cloud/overview for more information`
606
+ );
607
+ }
608
+ let localUrl = `http://localhost:${this.port}/graphql`;
609
+ let tinaCloudUrl = `${baseUrl}/${version2}/content/${clientId}/github/${branch}`;
610
+ let apiURL = this.isLocal ? `http://localhost:${this.port}/graphql` : `${baseUrl}/${version2}/content/${clientId}/github/${branch}`;
611
+ if (this.configManager.config.contentApiUrlOverride) {
612
+ apiURL = this.configManager.config.contentApiUrlOverride;
613
+ localUrl = apiURL;
614
+ tinaCloudUrl = apiURL;
615
+ }
616
+ return { apiURL, localUrl, tinaCloudUrl };
617
+ }
618
+ getApiURL() {
619
+ if (!this.apiURL)
620
+ throw new Error("apiURL not set. Please run execute() first");
621
+ return this.apiURL;
622
+ }
623
+ async genDatabaseClient() {
624
+ var _a, _b;
625
+ const authCollection = this.tinaSchema.getCollections().find((c) => c.isAuthCollection);
626
+ let authFields = [];
627
+ if (authCollection) {
628
+ const usersFields = (0, import_graphql6.mapUserFields)(authCollection, []);
629
+ if (usersFields.length === 0) {
630
+ throw new Error("No user field found");
631
+ }
632
+ if (usersFields.length > 1) {
633
+ throw new Error("Only one user field is allowed");
634
+ }
635
+ authFields = (_b = (_a = usersFields[0]) == null ? void 0 : _a.collectable) == null ? void 0 : _b.fields.map((f) => {
636
+ if (f.type !== "password" && f.type !== "object") {
637
+ if (f.uid) {
638
+ return `id:${f.name}`;
639
+ } else {
640
+ return `${f.name}`;
641
+ }
642
+ } else if (f.type === "password") {
643
+ return `_password: ${f.name} { passwordChangeRequired }`;
644
+ }
645
+ });
646
+ }
647
+ return `// @ts-nocheck
648
+ import { resolve } from "@tinacms/datalayer";
649
+ import type { TinaClient } from "tinacms/dist/client";
534
650
 
535
- // src/next/commands/dev-command/html.ts
536
- var errorHTML = `<style type="text/css">
537
- #no-assets-placeholder body {
538
- font-family: sans-serif;
539
- font-size: 16px;
540
- line-height: 1.4;
541
- color: #333;
542
- background-color: #f5f5f5;
543
- }
544
- #no-assets-placeholder {
545
- max-width: 600px;
546
- margin: 0 auto;
547
- padding: 40px;
548
- text-align: center;
549
- background-color: #fff;
550
- box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1);
651
+ import { queries } from "./types";
652
+ import database from "../database";
653
+
654
+ export async function databaseRequest({ query, variables, user }) {
655
+ const result = await resolve({
656
+ config: {
657
+ useRelativeMedia: true,
658
+ },
659
+ database,
660
+ query,
661
+ variables,
662
+ verbose: true,
663
+ ctxUser: user,
664
+ });
665
+
666
+ return result;
551
667
  }
552
- #no-assets-placeholder h1 {
553
- font-size: 24px;
554
- margin-bottom: 20px;
555
- }
556
- #no-assets-placeholder p {
557
- margin-bottom: 10px;
668
+
669
+ export async function authenticate({ username, password }) {
670
+ return databaseRequest({
671
+ query: \`query auth($username:String!, $password:String!) {
672
+ authenticate(sub:$username, password:$password) {
673
+ ${authFields.join(" ")}
674
+ }
675
+ }\`,
676
+ variables: { username, password },
677
+ })
558
678
  }
559
- #no-assets-placeholder a {
560
- color: #0077cc;
561
- text-decoration: none;
679
+
680
+ export async function authorize(user: { sub: string }) {
681
+ return databaseRequest({
682
+ query: \`query authz { authorize { ${authFields.join(" ")}} }\`,
683
+ variables: {},
684
+ user
685
+ })
562
686
  }
563
- #no-assets-placeholder a:hover {
564
- text-decoration: underline;
687
+
688
+ function createDatabaseClient<GenQueries = Record<string, unknown>>({
689
+ queries,
690
+ }: {
691
+ queries: (client: {
692
+ request: TinaClient<GenQueries>["request"];
693
+ }) => GenQueries;
694
+ }) {
695
+ const request = async ({ query, variables, user }) => {
696
+ const data = await databaseRequest({ query, variables, user });
697
+ return { data: data.data as any, query, variables, errors: data.errors || null };
698
+ };
699
+ const q = queries({
700
+ request,
701
+ });
702
+ return { queries: q, request, authenticate, authorize };
565
703
  }
566
- </style>
567
- <div id="no-assets-placeholder">
568
- <h1>Failed loading TinaCMS assets</h1>
569
- <p>
570
- Your TinaCMS configuration may be misconfigured, and we could not load
571
- the assets for this page.
572
- </p>
573
- <p>
574
- Please visit <a href="https://tina.io/docs/tina-cloud/faq/#how-do-i-resolve-failed-loading-tinacms-assets-error">this doc</a> for help.
575
- </p>
576
- </div>
577
- </div>`.trim().replace(/[\r\n\s]+/g, " ");
578
- var devHTML = (port) => `<!DOCTYPE html>
579
- <html lang="en">
580
- <head>
581
- <meta charset="UTF-8" />
582
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
583
- <title>TinaCMS</title>
584
- </head>
585
704
 
586
- <!-- if development -->
587
- <script type="module">
588
- import RefreshRuntime from 'http://localhost:${port}/@react-refresh'
589
- RefreshRuntime.injectIntoGlobalHook(window)
590
- window.$RefreshReg$ = () => {}
591
- window.$RefreshSig$ = () => (type) => type
592
- window.__vite_plugin_react_preamble_installed__ = true
593
- </script>
594
- <script type="module" src="http://localhost:${port}/@vite/client"></script>
595
- <script>
596
- function handleLoadError() {
597
- // Assets have failed to load
598
- document.getElementById('root').innerHTML = '${errorHTML}';
599
- }
600
- </script>
601
- <script
602
- type="module"
603
- src="http://localhost:${port}/src/main.tsx"
604
- onerror="handleLoadError()"
605
- ></script>
606
- <body class="tina-tailwind">
607
- <div id="root"></div>
608
- </body>
609
- </html>`;
705
+ export const databaseClient = createDatabaseClient({ queries });
610
706
 
611
- // src/utils/theme.ts
612
- var import_chalk3 = __toESM(require("chalk"));
613
- var successText = import_chalk3.default.bold.green;
614
- var focusText = import_chalk3.default.bold;
615
- var dangerText = import_chalk3.default.bold.red;
616
- var neutralText = import_chalk3.default.bold.cyan;
617
- var linkText = import_chalk3.default.bold.cyan;
618
- var labelText = import_chalk3.default.bold;
619
- var cmdText = import_chalk3.default.inverse;
620
- var indentedCmd = (str) => {
621
- return ` \u2503 ` + str;
707
+ export const client = databaseClient;
708
+
709
+ export default databaseClient;
710
+ `;
711
+ }
712
+ async genClient() {
713
+ var _a, _b, _c;
714
+ const token = (_a = this.configManager.config) == null ? void 0 : _a.token;
715
+ const errorPolicy = (_c = (_b = this.configManager.config) == null ? void 0 : _b.client) == null ? void 0 : _c.errorPolicy;
716
+ const apiURL = this.getApiURL();
717
+ const clientString = `import { createClient } from "tinacms/dist/client";
718
+ import { queries } from "./types";
719
+ export const client = createClient({ ${this.noClientBuildCache === false ? `cacheDir: '${(0, import_normalize_path.default)(
720
+ this.configManager.generatedCachePath
721
+ )}', ` : ""}url: '${apiURL}', token: '${token}', queries, ${errorPolicy ? `errorPolicy: '${errorPolicy}'` : ""} });
722
+ export default client;
723
+ `;
724
+ return { apiURL, clientString };
725
+ }
726
+ async genTypes() {
727
+ const typescriptTypes = await generateTypes(
728
+ this.schema,
729
+ this.configManager.userQueriesAndFragmentsGlob,
730
+ this.configManager.generatedQueriesAndFragmentsGlob,
731
+ this.getApiURL()
732
+ );
733
+ const codeString = `//@ts-nocheck
734
+ // DO NOT MODIFY THIS FILE. This file is automatically generated by Tina
735
+ export function gql(strings: TemplateStringsArray, ...args: string[]): string {
736
+ let str = ''
737
+ strings.forEach((string, i) => {
738
+ str += string + (args[i] || '')
739
+ })
740
+ return str
741
+ }
742
+ ${typescriptTypes}
743
+ `;
744
+ const schemaString = `# DO NOT MODIFY THIS FILE. This file is automatically generated by Tina
745
+ ${(0, import_graphql5.printSchema)(this.schema)}
746
+ schema {
747
+ query: Query
748
+ mutation: Mutation
749
+ }
750
+ `;
751
+ return { codeString, schemaString };
752
+ }
622
753
  };
623
- var indentText = (str) => {
624
- return String(str).split("\n").map((line) => ` ${line}`).join("\n");
754
+ var maybeWarnFragmentSize = async (filepath) => {
755
+ if (
756
+ // is the file bigger than 100kb?
757
+ (await import_fs_extra.default.stat(filepath)).size > // convert to 100 kb to bytes
758
+ 100 * 1024
759
+ ) {
760
+ console.warn(
761
+ "Warning: frags.gql is very large (>100kb). Consider setting the reference depth to 1 or 0. See code snippet below."
762
+ );
763
+ console.log(
764
+ `const schema = defineSchema({
765
+ client: {
766
+ referenceDepth: 1,
767
+ },
768
+ // ...
769
+ })`
770
+ );
771
+ }
772
+ };
773
+ var unlinkIfExists = async (filepath) => {
774
+ if (import_fs_extra.default.existsSync(filepath)) {
775
+ import_fs_extra.default.unlinkSync(filepath);
776
+ }
625
777
  };
626
- var logText = import_chalk3.default.italic.gray;
627
- var warnText = import_chalk3.default.yellowBright.bgBlack;
628
- var titleText = import_chalk3.default.bgHex("d2f1f8").hex("ec4816");
629
- var CONFIRMATION_TEXT = import_chalk3.default.dim("enter to confirm");
630
-
631
- // src/next/commands/dev-command/server/index.ts
632
- var import_vite3 = require("vite");
633
778
 
634
- // src/next/vite/index.ts
635
- var import_node_path2 = __toESM(require("path"));
636
- var import_plugin_react = __toESM(require("@vitejs/plugin-react"));
779
+ // src/next/config-manager.ts
637
780
  var import_fs_extra2 = __toESM(require("fs-extra"));
781
+ var import_path2 = __toESM(require("path"));
782
+ var import_os = __toESM(require("os"));
783
+ var esbuild = __toESM(require("esbuild"));
784
+ var dotenv = __toESM(require("dotenv"));
638
785
  var import_normalize_path2 = __toESM(require("normalize-path"));
639
- var import_vite = require("vite");
640
-
641
- // src/next/vite/tailwind.ts
642
- var import_node_path = __toESM(require("path"));
643
- var import_aspect_ratio = __toESM(require("@tailwindcss/aspect-ratio"));
644
- var import_container_queries = __toESM(require("@tailwindcss/container-queries"));
645
- var import_typography = __toESM(require("@tailwindcss/typography"));
646
- var import_tailwindcss = __toESM(require("tailwindcss"));
647
- var import_defaultTheme = __toESM(require("tailwindcss/defaultTheme.js"));
648
- var tinaTailwind = (spaPath, prebuildFilePath) => {
649
- return {
650
- name: "vite-plugin-tina",
651
- // @ts-ignore
652
- config: (viteConfig) => {
653
- const plugins = [];
654
- const content = [
655
- import_node_path.default.join(spaPath, "src/**/*.{vue,js,ts,jsx,tsx,svelte}"),
656
- prebuildFilePath,
657
- require.resolve("tinacms")
658
- ];
659
- const tw = (0, import_tailwindcss.default)({
660
- theme: {
661
- columns: {
662
- auto: "auto",
663
- 1: "1",
664
- 2: "2",
665
- 3: "3",
666
- 4: "4",
667
- 5: "5",
668
- 6: "6",
669
- 7: "7",
670
- 8: "8",
671
- 9: "9",
672
- 10: "10",
673
- 11: "11",
674
- 12: "12",
675
- "3xs": "256px",
676
- "2xs": "288px",
677
- xs: "320px",
678
- sm: "384px",
679
- md: "448px",
680
- lg: "512px",
681
- xl: "576px",
682
- "2xl": "672px",
683
- "3xl": "768px",
684
- "4xl": "896px",
685
- "5xl": "1024px",
686
- "6xl": "1152px",
687
- "7xl": "1280px"
688
- },
689
- spacing: {
690
- px: "1px",
691
- 0: "0px",
692
- 0.5: "2px",
693
- 1: "4px",
694
- 1.5: "6px",
695
- 2: "8px",
696
- 2.5: "10px",
697
- 3: "12px",
698
- 3.5: "14px",
699
- 4: "16px",
700
- 5: "20px",
701
- 6: "24px",
702
- 7: "28px",
703
- 8: "32px",
704
- 9: "36px",
705
- 10: "40px",
706
- 11: "44px",
707
- 12: "48px",
708
- 14: "56px",
709
- 16: "64px",
710
- 18: "72px",
711
- 20: "80px",
712
- 24: "96px",
713
- 28: "114px",
714
- 32: "128px",
715
- 36: "144px",
716
- 40: "160px",
717
- 44: "176px",
718
- 48: "192px",
719
- 52: "208px",
720
- 56: "224px",
721
- 60: "240px",
722
- 64: "256px",
723
- 72: "288px",
724
- 80: "320px",
725
- 96: "384px"
726
- },
727
- borderRadius: {
728
- none: "0px",
729
- sm: "2px",
730
- DEFAULT: "4px",
731
- md: "6px",
732
- lg: "8px",
733
- xl: "12px",
734
- "2xl": "16px",
735
- "3xl": "24px",
736
- full: "9999px"
737
- },
738
- borderWidth: {
739
- DEFAULT: "1px",
740
- 0: "0",
741
- 2: "2px",
742
- 3: "3px",
743
- 4: "4px",
744
- 6: "6px",
745
- 8: "8px"
746
- },
747
- fontSize: {
748
- xs: ["13px", { lineHeight: "1.33" }],
749
- sm: ["14px", { lineHeight: "1.43" }],
750
- base: ["16px", { lineHeight: "1.5" }],
751
- md: ["16px", { lineHeight: "1.5" }],
752
- lg: ["18px", { lineHeight: "1.55" }],
753
- xl: ["20px", { lineHeight: "1.4" }],
754
- "2xl": ["24px", { lineHeight: "1.33" }],
755
- "3xl": ["30px", { lineHeight: "1.2" }],
756
- "4xl": ["36px", { lineHeight: "1.1" }],
757
- "5xl": ["48px", { lineHeight: "1" }],
758
- "6xl": ["60px", { lineHeight: "1" }],
759
- "7xl": ["72px", { lineHeight: "1" }],
760
- "8xl": ["96px", { lineHeight: "1" }],
761
- "9xl": ["128px", { lineHeight: "1" }]
762
- },
763
- opacity: {
764
- 0: "0",
765
- 5: ".05",
766
- 7: ".07",
767
- 10: ".1",
768
- 15: ".15",
769
- 20: ".2",
770
- 25: ".25",
771
- 30: ".3",
772
- 40: ".4",
773
- 50: ".5",
774
- 60: ".6",
775
- 70: ".7",
776
- 75: ".75",
777
- 80: ".8",
778
- 90: ".9",
779
- 100: "1"
780
- },
781
- zIndex: {
782
- "-1": "-1",
783
- base: "9000",
784
- panel: "9400",
785
- menu: "9800",
786
- chrome: "10200",
787
- overlay: "10600",
788
- modal: "10800",
789
- 0: "0",
790
- 10: "10",
791
- 20: "20",
792
- 30: "30",
793
- 40: "40",
794
- 25: "25",
795
- 50: "50",
796
- 75: "75",
797
- 100: "100",
798
- auto: "auto"
799
- },
800
- extend: {
801
- scale: {
802
- 97: ".97",
803
- 103: "1.03"
804
- },
805
- transitionDuration: {
806
- 0: "0ms",
807
- 2e3: "2000ms"
808
- },
809
- boxShadow: {
810
- xs: "0 0 0 1px rgba(0, 0, 0, 0.05)",
811
- outline: "0 0 0 3px rgba(66, 153, 225, 0.5)"
812
- },
813
- colors: {
814
- blue: {
815
- 50: "#DCEEFF",
816
- 100: "#B4DBFF",
817
- 200: "#85C5FE",
818
- 300: "#4EABFE",
819
- 400: "#2296fe",
820
- 500: "#0084FF",
821
- 600: "#0574e4",
822
- 700: "#0D5DBD",
823
- 800: "#144696",
824
- 900: "#1D2C6C",
825
- 1e3: "#241748"
826
- },
827
- gray: {
828
- 50: "#F6F6F9",
829
- 100: "#EDECF3",
830
- 150: "#E6E3EF",
831
- 200: "#E1DDEC",
832
- 250: "#C9C5D5",
833
- 300: "#b2adbe",
834
- 400: "#918c9e",
835
- 500: "#716c7f",
836
- 600: "#565165",
837
- 700: "#433e52",
838
- 800: "#363145",
839
- 900: "#252336",
840
- 1e3: "#1c1b2e"
841
- },
842
- orange: {
843
- 400: "#EB6337",
844
- 500: "#EC4815",
845
- 600: "#DC4419"
846
- },
847
- background: "#FFFFFF",
848
- foreground: "#0A0A0A",
849
- muted: "#F5F5F5",
850
- "muted-foreground": "#737373",
851
- popover: "#FFFFFF",
852
- "popover-foreground": "#0A0A0A",
853
- card: "#FFFFFF",
854
- "card-foreground": "#0A0A0A",
855
- border: "#E5E5E5",
856
- input: "#E5E5E5",
857
- primary: "#171717",
858
- "primary-foreground": "#FAFAFA",
859
- secondary: "#F5F5F5",
860
- "secondary-foreground": "#171717",
861
- accent: "#F5F5F5",
862
- "accent-foreground": "#171717",
863
- destructive: "#FF3B3B",
864
- "destructive-foreground": "#FAFAFA",
865
- ring: "#0A0A0A"
866
- },
867
- fontFamily: {
868
- sans: ["Inter", ...import_defaultTheme.default.fontFamily.sans]
869
- },
870
- lineHeight: {
871
- 3: "12px",
872
- 4: "16px",
873
- 5: "20px",
874
- 6: "24px",
875
- 7: "28px",
876
- 8: "32px",
877
- 9: "36px",
878
- 10: "40px"
879
- },
880
- maxWidth: {
881
- form: "900px"
882
- },
883
- screens: {
884
- xs: "320px",
885
- sm: "560px",
886
- md: "720px",
887
- lg: "1030px"
888
- }
889
- }
890
- },
891
- content,
892
- plugins: [
893
- (0, import_typography.default)({ className: "tina-prose" }),
894
- import_aspect_ratio.default,
895
- import_container_queries.default
896
- ]
897
- });
898
- plugins.push(tw);
899
- return {
900
- css: {
901
- postcss: {
902
- plugins
903
- }
904
- }
905
- };
906
- }
907
- };
908
- };
909
-
910
- // src/next/vite/index.ts
911
- async function listFilesRecursively({
912
- directoryPath,
913
- config: config2,
914
- roothPath
915
- }) {
916
- const fullDirectoryPath = import_node_path2.default.join(
917
- roothPath,
918
- config2.publicFolder,
919
- directoryPath
920
- );
921
- const exists = await import_fs_extra2.default.pathExists(fullDirectoryPath);
922
- if (!exists) {
923
- return { "0": [] };
786
+ var import_chalk3 = __toESM(require("chalk"));
787
+ var TINA_FOLDER = "tina";
788
+ var LEGACY_TINA_FOLDER = ".tina";
789
+ var GENERATED_FOLDER = "__generated__";
790
+ var GRAPHQL_JSON_FILE = "_graphql.json";
791
+ var GRAPHQL_GQL_FILE = "schema.gql";
792
+ var SCHEMA_JSON_FILE = "_schema.json";
793
+ var LOOKUP_JSON_FILE = "_lookup.json";
794
+ var ConfigManager = class {
795
+ constructor({
796
+ rootPath = process.cwd(),
797
+ tinaGraphQLVersion,
798
+ legacyNoSDK
799
+ }) {
800
+ this.rootPath = (0, import_normalize_path2.default)(rootPath);
801
+ this.tinaGraphQLVersionFromCLI = tinaGraphQLVersion;
802
+ this.legacyNoSDK = legacyNoSDK;
924
803
  }
925
- const items = await import_fs_extra2.default.readdir(fullDirectoryPath);
926
- const staticMediaItems = [];
927
- for (const item of items) {
928
- const itemPath = import_node_path2.default.join(fullDirectoryPath, item);
929
- const stats = await import_fs_extra2.default.promises.lstat(itemPath);
930
- const staticMediaItem = {
931
- id: item,
932
- filename: item,
933
- type: stats.isDirectory() ? "dir" : "file",
934
- directory: `${directoryPath.replace(config2.mediaRoot, "")}`,
935
- src: `/${import_node_path2.default.join(directoryPath, item)}`,
936
- thumbnails: {
937
- "75x75": `/${import_node_path2.default.join(directoryPath, item)}`,
938
- "400x400": `/${import_node_path2.default.join(directoryPath, item)}`,
939
- "1000x1000": `/${import_node_path2.default.join(directoryPath, item)}`
940
- }
941
- };
942
- if (stats.isDirectory()) {
943
- staticMediaItem.children = await listFilesRecursively({
944
- directoryPath: import_node_path2.default.join(directoryPath, item),
945
- config: config2,
946
- roothPath
947
- });
948
- }
949
- staticMediaItems.push(staticMediaItem);
804
+ isUsingTs() {
805
+ return [".ts", ".tsx"].includes(import_path2.default.extname(this.tinaConfigFilePath));
950
806
  }
951
- function chunkArrayIntoObject(array, chunkSize) {
952
- const result = {};
953
- for (let i = 0; i < array.length; i += chunkSize) {
954
- const chunkKey = `${i / chunkSize * 20}`;
955
- result[chunkKey] = array.slice(i, i + chunkSize);
807
+ hasSelfHostedConfig() {
808
+ return !!this.selfHostedDatabaseFilePath;
809
+ }
810
+ hasSeparateContentRoot() {
811
+ return this.rootPath !== this.contentRootPath;
812
+ }
813
+ shouldSkipSDK() {
814
+ var _a;
815
+ if (this.legacyNoSDK) {
816
+ return this.legacyNoSDK;
956
817
  }
957
- return result;
818
+ return ((_a = this.config.client) == null ? void 0 : _a.skip) || false;
958
819
  }
959
- return chunkArrayIntoObject(staticMediaItems, 20);
960
- }
961
- var createConfig = async ({
962
- configManager,
963
- apiURL,
964
- plugins = [],
965
- noWatch,
966
- rollupOptions
967
- }) => {
968
- var _a, _b, _c, _d, _e, _f, _g, _h;
969
- const publicEnv = {};
970
- Object.keys(process.env).forEach((key) => {
971
- if (key.startsWith("TINA_PUBLIC_") || key.startsWith("NEXT_PUBLIC_") || key === "NODE_ENV" || key === "HEAD") {
972
- try {
973
- if (typeof process.env[key] === "string") {
974
- publicEnv[key] = process.env[key];
975
- } else {
976
- publicEnv[key] = JSON.stringify(process.env[key]);
977
- }
978
- } catch (error) {
979
- console.warn(
980
- `Could not stringify public env process.env.${key} env variable`
820
+ async processConfig() {
821
+ this.tinaFolderPath = await this.getTinaFolderPath(this.rootPath);
822
+ this.envFilePath = import_path2.default.resolve(
823
+ import_path2.default.join(this.tinaFolderPath, "..", ".env")
824
+ );
825
+ dotenv.config({ path: this.envFilePath });
826
+ this.tinaConfigFilePath = await this.getPathWithExtension(
827
+ import_path2.default.join(this.tinaFolderPath, "config")
828
+ );
829
+ if (!this.tinaConfigFilePath) {
830
+ throw new Error(
831
+ `Unable to find config file in ${this.tinaFolderPath}. Looking for a file named "config.{ts,tsx,js,jsx}"`
832
+ );
833
+ }
834
+ this.selfHostedDatabaseFilePath = await this.getPathWithExtension(
835
+ import_path2.default.join(this.tinaFolderPath, "database")
836
+ );
837
+ this.generatedFolderPath = import_path2.default.join(this.tinaFolderPath, GENERATED_FOLDER);
838
+ this.generatedCachePath = import_path2.default.join(
839
+ this.generatedFolderPath,
840
+ ".cache",
841
+ String((/* @__PURE__ */ new Date()).getTime())
842
+ );
843
+ this.generatedGraphQLGQLPath = import_path2.default.join(
844
+ this.generatedFolderPath,
845
+ GRAPHQL_GQL_FILE
846
+ );
847
+ this.generatedGraphQLJSONPath = import_path2.default.join(
848
+ this.generatedFolderPath,
849
+ GRAPHQL_JSON_FILE
850
+ );
851
+ this.generatedSchemaJSONPath = import_path2.default.join(
852
+ this.generatedFolderPath,
853
+ SCHEMA_JSON_FILE
854
+ );
855
+ this.generatedLookupJSONPath = import_path2.default.join(
856
+ this.generatedFolderPath,
857
+ LOOKUP_JSON_FILE
858
+ );
859
+ this.generatedQueriesFilePath = import_path2.default.join(
860
+ this.generatedFolderPath,
861
+ "queries.gql"
862
+ );
863
+ this.generatedFragmentsFilePath = import_path2.default.join(
864
+ this.generatedFolderPath,
865
+ "frags.gql"
866
+ );
867
+ this.generatedTypesTSFilePath = import_path2.default.join(
868
+ this.generatedFolderPath,
869
+ "types.ts"
870
+ );
871
+ this.generatedTypesJSFilePath = import_path2.default.join(
872
+ this.generatedFolderPath,
873
+ "types.js"
874
+ );
875
+ this.generatedTypesDFilePath = import_path2.default.join(
876
+ this.generatedFolderPath,
877
+ "types.d.ts"
878
+ );
879
+ this.userQueriesAndFragmentsGlob = import_path2.default.join(
880
+ this.tinaFolderPath,
881
+ "queries/**/*.{graphql,gql}"
882
+ );
883
+ this.generatedQueriesAndFragmentsGlob = import_path2.default.join(
884
+ this.generatedFolderPath,
885
+ "*.{graphql,gql}"
886
+ );
887
+ this.generatedClientTSFilePath = import_path2.default.join(
888
+ this.generatedFolderPath,
889
+ "client.ts"
890
+ );
891
+ this.generatedClientJSFilePath = import_path2.default.join(
892
+ this.generatedFolderPath,
893
+ "client.js"
894
+ );
895
+ this.generatedClientDFilePath = import_path2.default.join(
896
+ this.generatedFolderPath,
897
+ "client.d.ts"
898
+ );
899
+ this.generatedDatabaseClientDFilePath = import_path2.default.join(
900
+ this.generatedFolderPath,
901
+ "databaseClient.d.ts"
902
+ );
903
+ this.generatedDatabaseClientTSFilePath = import_path2.default.join(
904
+ this.generatedFolderPath,
905
+ "databaseClient.ts"
906
+ );
907
+ this.generatedDatabaseClientJSFilePath = import_path2.default.join(
908
+ this.generatedFolderPath,
909
+ "databaseClient.js"
910
+ );
911
+ const clientExists = this.isUsingTs() ? await import_fs_extra2.default.pathExists(this.generatedClientTSFilePath) : await import_fs_extra2.default.pathExists(this.generatedClientJSFilePath);
912
+ if (!clientExists) {
913
+ const file = "export default ()=>({})\nexport const client = ()=>({})";
914
+ if (this.isUsingTs()) {
915
+ await import_fs_extra2.default.outputFile(this.generatedClientTSFilePath, file);
916
+ } else {
917
+ await import_fs_extra2.default.outputFile(this.generatedClientJSFilePath, file);
918
+ }
919
+ }
920
+ const { config: config2, prebuildPath, watchList } = await this.loadConfigFile(
921
+ this.generatedFolderPath,
922
+ this.tinaConfigFilePath
923
+ );
924
+ this.watchList = watchList;
925
+ this.config = config2;
926
+ this.prebuildFilePath = prebuildPath;
927
+ this.publicFolderPath = import_path2.default.join(
928
+ this.rootPath,
929
+ this.config.build.publicFolder
930
+ );
931
+ this.outputFolderPath = import_path2.default.join(
932
+ this.publicFolderPath,
933
+ this.config.build.outputFolder
934
+ );
935
+ this.outputHTMLFilePath = import_path2.default.join(this.outputFolderPath, "index.html");
936
+ this.outputGitignorePath = import_path2.default.join(this.outputFolderPath, ".gitignore");
937
+ const fullLocalContentPath = import_path2.default.join(
938
+ this.tinaFolderPath,
939
+ this.config.localContentPath || ""
940
+ );
941
+ if (this.config.localContentPath) {
942
+ const localContentPathExists = await import_fs_extra2.default.pathExists(fullLocalContentPath);
943
+ if (localContentPathExists) {
944
+ logger.info(`Using separate content repo at ${fullLocalContentPath}`);
945
+ this.contentRootPath = fullLocalContentPath;
946
+ } else {
947
+ logger.warn(
948
+ `${import_chalk3.default.yellow("Warning:")} The localContentPath ${import_chalk3.default.cyan(
949
+ fullLocalContentPath
950
+ )} does not exist. Please create it or remove the localContentPath from your config file at ${import_chalk3.default.cyan(
951
+ this.tinaConfigFilePath
952
+ )}`
981
953
  );
982
- console.warn(error);
983
954
  }
984
955
  }
985
- });
986
- const staticMediaPath = import_node_path2.default.join(
987
- configManager.generatedFolderPath,
988
- "static-media.json"
989
- );
990
- if ((_b = (_a = configManager.config.media) == null ? void 0 : _a.tina) == null ? void 0 : _b.static) {
991
- const staticMedia = await listFilesRecursively({
992
- directoryPath: ((_c = configManager.config.media.tina) == null ? void 0 : _c.mediaRoot) || "",
993
- config: configManager.config.media.tina,
994
- roothPath: configManager.rootPath
995
- });
996
- await import_fs_extra2.default.outputFile(staticMediaPath, JSON.stringify(staticMedia, null, 2));
997
- } else {
998
- await import_fs_extra2.default.outputFile(staticMediaPath, `[]`);
956
+ if (!this.contentRootPath) {
957
+ this.contentRootPath = this.rootPath;
958
+ }
959
+ this.generatedFolderPathContentRepo = import_path2.default.join(
960
+ await this.getTinaFolderPath(this.contentRootPath),
961
+ GENERATED_FOLDER
962
+ );
963
+ this.spaMainPath = require.resolve("@tinacms/app");
964
+ this.spaRootPath = import_path2.default.join(this.spaMainPath, "..", "..");
999
965
  }
1000
- const alias = {
1001
- TINA_IMPORT: configManager.prebuildFilePath,
1002
- SCHEMA_IMPORT: configManager.generatedGraphQLJSONPath,
1003
- STATIC_MEDIA_IMPORT: staticMediaPath,
1004
- crypto: import_node_path2.default.join(configManager.spaRootPath, "src", "dummy-client.ts"),
1005
- fs: import_node_path2.default.join(configManager.spaRootPath, "src", "dummy-client.ts"),
1006
- os: import_node_path2.default.join(configManager.spaRootPath, "src", "dummy-client.ts"),
1007
- path: import_node_path2.default.join(configManager.spaRootPath, "src", "dummy-client.ts")
1008
- };
1009
- if (configManager.shouldSkipSDK()) {
1010
- alias["CLIENT_IMPORT"] = import_node_path2.default.join(
1011
- configManager.spaRootPath,
1012
- "src",
1013
- "dummy-client.ts"
966
+ async getTinaFolderPath(rootPath) {
967
+ const tinaFolderPath = import_path2.default.join(rootPath, TINA_FOLDER);
968
+ const tinaFolderExists = await import_fs_extra2.default.pathExists(tinaFolderPath);
969
+ if (tinaFolderExists) {
970
+ this.isUsingLegacyFolder = false;
971
+ return tinaFolderPath;
972
+ }
973
+ const legacyFolderPath = import_path2.default.join(rootPath, LEGACY_TINA_FOLDER);
974
+ const legacyFolderExists = await import_fs_extra2.default.pathExists(legacyFolderPath);
975
+ if (legacyFolderExists) {
976
+ this.isUsingLegacyFolder = true;
977
+ return legacyFolderPath;
978
+ }
979
+ throw new Error(
980
+ `Unable to find Tina folder, if you're working in folder outside of the Tina config be sure to specify --rootPath`
1014
981
  );
1015
- } else {
1016
- alias["CLIENT_IMPORT"] = configManager.isUsingTs() ? configManager.generatedTypesTSFilePath : configManager.generatedTypesJSFilePath;
1017
982
  }
1018
- let basePath;
1019
- if (configManager.config.build.basePath) {
1020
- basePath = configManager.config.build.basePath;
983
+ getTinaGraphQLVersion() {
984
+ if (this.tinaGraphQLVersionFromCLI) {
985
+ const version2 = this.tinaGraphQLVersionFromCLI.split(".");
986
+ return {
987
+ fullVersion: this.tinaGraphQLVersionFromCLI,
988
+ major: version2[0] || "x",
989
+ minor: version2[1] || "x",
990
+ patch: version2[2] || "x"
991
+ };
992
+ }
993
+ const generatedSchema = import_fs_extra2.default.readJSONSync(this.generatedSchemaJSONPath);
994
+ if (!generatedSchema || !(typeof (generatedSchema == null ? void 0 : generatedSchema.version) !== "undefined")) {
995
+ throw new Error(
996
+ `Can not find Tina GraphQL version in ${this.generatedSchemaJSONPath}`
997
+ );
998
+ }
999
+ return generatedSchema.version;
1021
1000
  }
1022
- const fullVersion = configManager.getTinaGraphQLVersion();
1023
- const version2 = `${fullVersion.major}.${fullVersion.minor}`;
1024
- const config2 = {
1025
- root: configManager.spaRootPath,
1026
- base: `/${basePath ? `${(0, import_normalize_path2.default)(basePath)}/` : ""}${(0, import_normalize_path2.default)(
1027
- configManager.config.build.outputFolder
1028
- )}/`,
1029
- appType: "spa",
1030
- resolve: {
1031
- alias,
1032
- dedupe: ["graphql", "tinacms", "react", "react-dom", "react-router-dom"]
1033
- },
1034
- define: {
1035
- /**
1036
- * Since we prebuild the config.ts, it's possible for modules to be loaded which make
1037
- * use of `process`. The main scenario where this is an issue is when co-locating schema
1038
- * definitions with source files, and specifically source files which impor from NextJS.
1039
- *
1040
- * Some examples of what NextJS uses for `process.env` are:
1041
- * - `process.env.__NEXT_TRAILING_SLASH`
1042
- * - `process.env.__NEXT_CROSS_ORIGIN`
1043
- * - `process.env.__NEXT_I18N_SUPPORT`
1044
- *
1045
- * Also, interestingly some of the advice for handling this doesn't work, references to replacing
1046
- * `process.env` with `{}` are problematic, because browsers don't understand the `{}.` syntax,
1047
- * but node does. This was a surprise, but using `new Object()` seems to do the trick.
1048
- */
1049
- "process.env": `new Object(${JSON.stringify(publicEnv)})`,
1050
- // Used by picomatch https://github.com/micromatch/picomatch/blob/master/lib/utils.js#L4
1051
- "process.platform": `"${process.platform}"`,
1052
- __API_URL__: `"${apiURL}"`,
1053
- __BASE_PATH__: `"${((_e = (_d = configManager.config) == null ? void 0 : _d.build) == null ? void 0 : _e.basePath) || ""}"`,
1054
- __TINA_GRAPHQL_VERSION__: version2
1055
- },
1056
- logLevel: "error",
1057
- // Vite import warnings are noisy
1058
- optimizeDeps: {
1059
- force: true,
1060
- // Not 100% sure why this isn't being picked up automatically, this works from within the monorepo
1061
- // but breaks externally
1062
- include: ["react/jsx-runtime", "react/jsx-dev-runtime"]
1063
- },
1064
- server: {
1065
- host: (_h = (_g = (_f = configManager.config) == null ? void 0 : _f.build) == null ? void 0 : _g.host) != null ? _h : false,
1066
- watch: noWatch ? {
1067
- ignored: ["**/*"]
1068
- } : {
1069
- // Ignore everything except for the alias fields we specified above
1070
- ignored: [
1071
- `${configManager.tinaFolderPath}/**/!(config.prebuild.jsx|_graphql.json)`
1072
- ]
1073
- },
1074
- fs: {
1075
- strict: false
1076
- }
1077
- },
1078
- build: {
1079
- sourcemap: false,
1080
- outDir: configManager.outputFolderPath,
1081
- emptyOutDir: true,
1082
- rollupOptions
1083
- },
1084
- plugins: [
1085
- /**
1086
- * `splitVendorChunkPlugin` is needed because `tinacms` is quite large,
1087
- * Vite's chunking strategy chokes on memory issues for smaller machines (ie. on CI).
1088
- */
1089
- (0, import_plugin_react.default)({
1090
- babel: {
1091
- // Supresses the warning [NOTE] babel The code generator has deoptimised the styling of
1092
- compact: true
1093
- }
1094
- }),
1095
- (0, import_vite.splitVendorChunkPlugin)(),
1096
- tinaTailwind(configManager.spaRootPath, configManager.prebuildFilePath),
1097
- ...plugins
1098
- ]
1099
- };
1100
- return config2;
1101
- };
1102
-
1103
- // src/next/vite/plugins.ts
1104
- var import_pluginutils = require("@rollup/pluginutils");
1105
- var import_fs = __toESM(require("fs"));
1106
- var import_vite2 = require("vite");
1107
- var import_esbuild = require("esbuild");
1108
- var import_path3 = __toESM(require("path"));
1109
- var import_body_parser = __toESM(require("body-parser"));
1110
- var import_cors = __toESM(require("cors"));
1111
- var import_graphql = require("@tinacms/graphql");
1112
-
1113
- // src/next/commands/dev-command/server/media.ts
1114
- var import_fs_extra3 = __toESM(require("fs-extra"));
1115
- var import_path2 = __toESM(require("path"));
1116
- var import_busboy = __toESM(require("busboy"));
1117
- var createMediaRouter = (config2) => {
1118
- const mediaFolder = import_path2.default.join(
1119
- config2.rootPath,
1120
- config2.publicFolder,
1121
- config2.mediaRoot
1122
- );
1123
- const mediaModel = new MediaModel(config2);
1124
- const handleList = async (req, res) => {
1125
- const requestURL = new URL(req.url, config2.apiURL);
1126
- const folder = requestURL.pathname.replace("/media/list/", "");
1127
- const limit = requestURL.searchParams.get("limit");
1128
- const cursor = requestURL.searchParams.get("cursor");
1129
- const media = await mediaModel.listMedia({
1130
- searchPath: folder,
1131
- cursor,
1132
- limit
1001
+ printGeneratedClientFilePath() {
1002
+ if (this.isUsingTs()) {
1003
+ return this.generatedClientTSFilePath.replace(`${this.rootPath}/`, "");
1004
+ }
1005
+ return this.generatedClientJSFilePath.replace(`${this.rootPath}/`, "");
1006
+ }
1007
+ printGeneratedTypesFilePath() {
1008
+ return this.generatedTypesTSFilePath.replace(`${this.rootPath}/`, "");
1009
+ }
1010
+ printoutputHTMLFilePath() {
1011
+ return this.outputHTMLFilePath.replace(`${this.publicFolderPath}/`, "");
1012
+ }
1013
+ printRelativePath(filename) {
1014
+ if (filename) {
1015
+ return filename.replace(/\\/g, "/").replace(`${this.rootPath}/`, "");
1016
+ }
1017
+ throw `No path provided to print`;
1018
+ }
1019
+ printPrebuildFilePath() {
1020
+ return this.prebuildFilePath.replace(/\\/g, "/").replace(`${this.rootPath}/${this.tinaFolderPath}/`, "");
1021
+ }
1022
+ printContentRelativePath(filename) {
1023
+ if (filename) {
1024
+ return filename.replace(/\\/g, "/").replace(`${this.contentRootPath}/`, "");
1025
+ }
1026
+ throw `No path provided to print`;
1027
+ }
1028
+ /**
1029
+ * Given a filepath without an extension, find the first match (eg. tsx, ts, jsx, js)
1030
+ */
1031
+ async getPathWithExtension(filepath) {
1032
+ const extensions = ["tsx", "ts", "jsx", "js"];
1033
+ let result;
1034
+ await Promise.all(
1035
+ extensions.map(async (ext) => {
1036
+ if (result) {
1037
+ return;
1038
+ }
1039
+ const filepathWithExtension = `${filepath}.${ext}`;
1040
+ const exists = import_fs_extra2.default.existsSync(filepathWithExtension);
1041
+ if (exists) {
1042
+ result = filepathWithExtension;
1043
+ }
1044
+ })
1045
+ );
1046
+ return result;
1047
+ }
1048
+ async loadDatabaseFile() {
1049
+ const tmpdir = import_path2.default.join(import_os.default.tmpdir(), Date.now().toString());
1050
+ const outfile = import_path2.default.join(tmpdir, "database.build.js");
1051
+ await esbuild.build({
1052
+ entryPoints: [this.selfHostedDatabaseFilePath],
1053
+ bundle: true,
1054
+ platform: "node",
1055
+ outfile,
1056
+ loader: loaders
1133
1057
  });
1134
- res.end(JSON.stringify(media));
1135
- };
1136
- const handleDelete = async (req, res) => {
1137
- const file = decodeURIComponent(req.url.slice("/media/".length));
1138
- const didDelete = await mediaModel.deleteMedia({ searchPath: file });
1139
- res.end(JSON.stringify(didDelete));
1140
- };
1141
- const handlePost = async function(req, res) {
1142
- const bb = (0, import_busboy.default)({ headers: req.headers });
1143
- bb.on("file", async (_name, file, _info) => {
1144
- var _a;
1145
- const fullPath = decodeURI((_a = req.url) == null ? void 0 : _a.slice("/media/upload/".length));
1146
- const saveTo = import_path2.default.join(mediaFolder, ...fullPath.split("/"));
1147
- await import_fs_extra3.default.ensureDir(import_path2.default.dirname(saveTo));
1148
- file.pipe(import_fs_extra3.default.createWriteStream(saveTo));
1058
+ const result = require(outfile);
1059
+ import_fs_extra2.default.removeSync(outfile);
1060
+ return result.default;
1061
+ }
1062
+ async loadConfigFile(generatedFolderPath, configFilePath) {
1063
+ const tmpdir = import_path2.default.join(import_os.default.tmpdir(), Date.now().toString());
1064
+ const preBuildConfigPath = import_path2.default.join(
1065
+ this.generatedFolderPath,
1066
+ "config.prebuild.jsx"
1067
+ );
1068
+ const outfile = import_path2.default.join(tmpdir, "config.build.jsx");
1069
+ const outfile2 = import_path2.default.join(tmpdir, "config.build.js");
1070
+ const tempTSConfigFile = import_path2.default.join(tmpdir, "tsconfig.json");
1071
+ import_fs_extra2.default.outputFileSync(tempTSConfigFile, "{}");
1072
+ const result2 = await esbuild.build({
1073
+ entryPoints: [configFilePath],
1074
+ bundle: true,
1075
+ target: ["es2020"],
1076
+ platform: "browser",
1077
+ format: "esm",
1078
+ logLevel: "silent",
1079
+ packages: "external",
1080
+ ignoreAnnotations: true,
1081
+ outfile: preBuildConfigPath,
1082
+ loader: loaders,
1083
+ metafile: true
1149
1084
  });
1150
- bb.on("error", (error) => {
1151
- res.statusCode = 500;
1152
- if (error instanceof Error) {
1153
- res.end(JSON.stringify({ message: error }));
1154
- } else {
1155
- res.end(JSON.stringify({ message: "Unknown error while uploading" }));
1085
+ const flattenedList = [];
1086
+ Object.keys(result2.metafile.inputs).forEach((key) => {
1087
+ if (key.includes("node_modules") || key.includes("__generated__")) {
1088
+ return;
1156
1089
  }
1090
+ flattenedList.push(key);
1157
1091
  });
1158
- bb.on("close", () => {
1159
- res.statusCode = 200;
1160
- res.end(JSON.stringify({ success: true }));
1092
+ await esbuild.build({
1093
+ entryPoints: [configFilePath],
1094
+ bundle: true,
1095
+ target: ["es2020"],
1096
+ logLevel: "silent",
1097
+ platform: "node",
1098
+ outfile,
1099
+ loader: loaders
1161
1100
  });
1162
- req.pipe(bb);
1163
- };
1164
- return { handleList, handleDelete, handlePost };
1165
- };
1166
- var parseMediaFolder = (str) => {
1167
- let returnString = str;
1168
- if (returnString.startsWith("/")) returnString = returnString.substr(1);
1169
- if (returnString.endsWith("/"))
1170
- returnString = returnString.substr(0, returnString.length - 1);
1171
- return returnString;
1172
- };
1173
- var MediaModel = class {
1174
- constructor({ rootPath, publicFolder, mediaRoot }) {
1175
- this.rootPath = rootPath;
1176
- this.mediaRoot = mediaRoot;
1177
- this.publicFolder = publicFolder;
1178
- }
1179
- async listMedia(args) {
1180
- try {
1181
- const folderPath = (0, import_path2.join)(
1182
- this.rootPath,
1183
- this.publicFolder,
1184
- this.mediaRoot,
1185
- decodeURIComponent(args.searchPath)
1186
- );
1187
- const searchPath = parseMediaFolder(args.searchPath);
1188
- if (!await import_fs_extra3.default.pathExists(folderPath)) {
1189
- return {
1190
- files: [],
1191
- directories: []
1192
- };
1193
- }
1194
- const filesStr = await import_fs_extra3.default.readdir(folderPath);
1195
- const filesProm = filesStr.map(async (file) => {
1196
- const filePath = (0, import_path2.join)(folderPath, file);
1197
- const stat = await import_fs_extra3.default.stat(filePath);
1198
- let src = `/${file}`;
1199
- const isFile = stat.isFile();
1200
- if (!isFile) {
1201
- return {
1202
- isFile,
1203
- size: stat.size,
1204
- src,
1205
- filename: file
1206
- };
1207
- }
1208
- if (searchPath) {
1209
- src = `/${searchPath}${src}`;
1210
- }
1211
- if (this.mediaRoot) {
1212
- src = `/${this.mediaRoot}${src}`;
1213
- }
1214
- return {
1215
- isFile,
1216
- size: stat.size,
1217
- src,
1218
- filename: file
1219
- };
1220
- });
1221
- const offset = Number(args.cursor) || 0;
1222
- const limit = Number(args.limit) || 20;
1223
- const rawItems = await Promise.all(filesProm);
1224
- const sortedItems = rawItems.sort((a, b) => {
1225
- if (a.isFile && !b.isFile) {
1226
- return 1;
1227
- }
1228
- if (!a.isFile && b.isFile) {
1229
- return -1;
1230
- }
1231
- return 0;
1232
- });
1233
- const limitItems = sortedItems.slice(offset, offset + limit);
1234
- const files = limitItems.filter((x) => x.isFile);
1235
- const directories = limitItems.filter((x) => !x.isFile).map((x) => x.src);
1236
- const cursor = rawItems.length > offset + limit ? String(offset + limit) : null;
1237
- return {
1238
- files,
1239
- directories,
1240
- cursor
1241
- };
1242
- } catch (error) {
1243
- console.error(error);
1244
- return {
1245
- files: [],
1246
- directories: [],
1247
- error: error == null ? void 0 : error.toString()
1248
- };
1249
- }
1250
- }
1251
- async deleteMedia(args) {
1101
+ await esbuild.build({
1102
+ entryPoints: [outfile],
1103
+ bundle: true,
1104
+ // Suppress warning about comparison with -0 from client module
1105
+ logLevel: "silent",
1106
+ platform: "node",
1107
+ outfile: outfile2,
1108
+ loader: loaders
1109
+ });
1110
+ let result;
1252
1111
  try {
1253
- const file = (0, import_path2.join)(
1254
- this.rootPath,
1255
- this.publicFolder,
1256
- this.mediaRoot,
1257
- decodeURIComponent(args.searchPath)
1258
- );
1259
- await import_fs_extra3.default.stat(file);
1260
- await import_fs_extra3.default.remove(file);
1261
- return { ok: true };
1262
- } catch (error) {
1263
- console.error(error);
1264
- return { ok: false, message: error == null ? void 0 : error.toString() };
1112
+ result = require(outfile2);
1113
+ } catch (e) {
1114
+ console.error("Unexpected error loading config");
1115
+ console.error(e);
1116
+ throw e;
1265
1117
  }
1118
+ import_fs_extra2.default.removeSync(outfile);
1119
+ import_fs_extra2.default.removeSync(outfile2);
1120
+ return {
1121
+ config: result.default,
1122
+ prebuildPath: preBuildConfigPath,
1123
+ watchList: flattenedList
1124
+ };
1266
1125
  }
1267
1126
  };
1268
-
1269
- // src/next/commands/dev-command/server/searchIndex.ts
1270
- var createSearchIndexRouter = ({
1271
- config: config2,
1272
- searchIndex
1273
- }) => {
1274
- const put = async (req, res) => {
1275
- const { docs } = req.body;
1276
- const result = await searchIndex.PUT(docs);
1277
- res.writeHead(200, { "Content-Type": "application/json" });
1278
- res.end(JSON.stringify({ result }));
1279
- };
1280
- const get = async (req, res) => {
1281
- const requestURL = new URL(req.url, config2.apiURL);
1282
- const query = requestURL.searchParams.get("q");
1283
- const optionsParam = requestURL.searchParams.get("options");
1284
- let options = {
1285
- DOCUMENTS: false
1286
- };
1287
- if (optionsParam) {
1288
- options = {
1289
- ...options,
1290
- ...JSON.parse(optionsParam)
1291
- };
1292
- }
1293
- res.writeHead(200, { "Content-Type": "application/json" });
1294
- if (query) {
1295
- const result = await searchIndex.QUERY(JSON.parse(query), options);
1296
- res.end(JSON.stringify(result));
1297
- } else {
1298
- res.end(JSON.stringify({ RESULT: [] }));
1299
- }
1300
- };
1301
- const del = async (req, res) => {
1302
- const requestURL = new URL(req.url, config2.apiURL);
1303
- const docId = requestURL.pathname.split("/").filter(Boolean).slice(1).join("/");
1304
- const result = await searchIndex.DELETE(docId);
1305
- res.writeHead(200, { "Content-Type": "application/json" });
1306
- res.end(JSON.stringify({ result }));
1307
- };
1308
- return { del, get, put };
1127
+ var loaders = {
1128
+ ".aac": "file",
1129
+ ".css": "file",
1130
+ ".eot": "file",
1131
+ ".flac": "file",
1132
+ ".gif": "file",
1133
+ ".jpeg": "file",
1134
+ ".jpg": "file",
1135
+ ".json": "json",
1136
+ ".mp3": "file",
1137
+ ".mp4": "file",
1138
+ ".ogg": "file",
1139
+ ".otf": "file",
1140
+ ".png": "file",
1141
+ ".svg": "file",
1142
+ ".ttf": "file",
1143
+ ".wav": "file",
1144
+ ".webm": "file",
1145
+ ".webp": "file",
1146
+ ".woff": "file",
1147
+ ".woff2": "file",
1148
+ ".js": "jsx",
1149
+ ".jsx": "jsx",
1150
+ ".tsx": "tsx"
1309
1151
  };
1310
1152
 
1311
- // src/next/vite/plugins.ts
1312
- var transformTsxPlugin = ({
1313
- configManager: _configManager
1314
- }) => {
1315
- const plug = {
1316
- name: "transform-tsx",
1317
- async transform(code, id) {
1318
- const extName = import_path3.default.extname(id);
1319
- if (extName.startsWith(".tsx") || extName.startsWith(".ts")) {
1320
- const result = await (0, import_esbuild.transform)(code, { loader: "tsx" });
1321
- return {
1322
- code: result.code
1323
- };
1324
- }
1325
- }
1326
- };
1327
- return plug;
1328
- };
1329
- var devServerEndPointsPlugin = ({
1330
- configManager,
1331
- apiURL,
1332
- database,
1333
- searchIndex,
1334
- databaseLock
1335
- }) => {
1336
- const plug = {
1337
- name: "graphql-endpoints",
1338
- configureServer(server) {
1339
- server.middlewares.use((0, import_cors.default)());
1340
- server.middlewares.use(import_body_parser.default.json({ limit: "5mb" }));
1341
- server.middlewares.use(async (req, res, next) => {
1342
- var _a;
1343
- const mediaPaths = (_a = configManager.config.media) == null ? void 0 : _a.tina;
1344
- const mediaRouter = createMediaRouter({
1345
- rootPath: configManager.rootPath,
1346
- apiURL,
1347
- publicFolder: parseMediaFolder((mediaPaths == null ? void 0 : mediaPaths.publicFolder) || ""),
1348
- mediaRoot: parseMediaFolder((mediaPaths == null ? void 0 : mediaPaths.mediaRoot) || "")
1349
- });
1350
- const searchIndexRouter = createSearchIndexRouter({
1351
- config: { apiURL, searchPath: "searchIndex" },
1352
- searchIndex
1353
- });
1354
- if (req.url.startsWith("/media/upload")) {
1355
- await mediaRouter.handlePost(req, res);
1356
- return;
1357
- }
1358
- if (req.url.startsWith("/media")) {
1359
- if (req.method === "DELETE") {
1360
- await mediaRouter.handleDelete(req, res);
1361
- return;
1362
- }
1363
- }
1364
- if (req.url.startsWith("/media/list")) {
1365
- await mediaRouter.handleList(req, res);
1366
- return;
1367
- }
1368
- if (req.url === "/altair") {
1369
- res.end(
1370
- JSON.stringify({
1371
- status: "The GraphQL playground has moved to <your-dev-url>/index.html#/graphql"
1372
- })
1373
- );
1374
- return;
1375
- }
1376
- if (req.url === "/graphql") {
1377
- const { query, variables } = req.body;
1378
- let result;
1379
- await databaseLock(async () => {
1380
- result = await (0, import_graphql.resolve)({
1381
- config: {
1382
- useRelativeMedia: true
1383
- },
1384
- database,
1385
- query,
1386
- variables,
1387
- verbose: false
1388
- });
1389
- });
1390
- res.end(JSON.stringify(result));
1391
- return;
1392
- }
1393
- if (req.url.startsWith("/searchIndex")) {
1394
- if (req.method === "POST") {
1395
- await searchIndexRouter.put(req, res);
1396
- } else if (req.method === "GET") {
1397
- await searchIndexRouter.get(req, res);
1398
- } else if (req.method === "DELETE") {
1399
- await searchIndexRouter.del(req, res);
1400
- }
1401
- return;
1402
- }
1403
- next();
1404
- });
1153
+ // src/next/database.ts
1154
+ var import_graphql7 = require("@tinacms/graphql");
1155
+ var import_readable_stream = require("readable-stream");
1156
+ var import_net = require("net");
1157
+ var import_many_level = require("many-level");
1158
+ var import_memory_level = require("memory-level");
1159
+ var createDBServer = (port) => {
1160
+ const levelHost = new import_many_level.ManyLevelHost(
1161
+ // @ts-ignore
1162
+ new import_memory_level.MemoryLevel({
1163
+ valueEncoding: "json"
1164
+ })
1165
+ );
1166
+ const dbServer = (0, import_net.createServer)(function(socket) {
1167
+ return (0, import_readable_stream.pipeline)(socket, levelHost.createRpcStream(), socket, () => {
1168
+ });
1169
+ });
1170
+ dbServer.once("error", (err) => {
1171
+ if ((err == null ? void 0 : err.code) === "EADDRINUSE") {
1172
+ throw new Error(
1173
+ `Tina Dev server is already in use. Datalayer server is busy on port ${port}`
1174
+ );
1405
1175
  }
1406
- };
1407
- return plug;
1176
+ });
1177
+ dbServer.listen(port);
1408
1178
  };
1409
- function viteTransformExtension({
1410
- exportAsDefault = true,
1411
- svgrOptions,
1412
- esbuildOptions,
1413
- include = "**/*.svg",
1414
- exclude
1415
- } = {}) {
1416
- const filter = (0, import_pluginutils.createFilter)(include, exclude);
1417
- return {
1418
- name: "vite-plugin-svgr",
1419
- async transform(code, id) {
1420
- if (filter(id)) {
1421
- const { transform: transform2 } = await Promise.resolve().then(() => __toESM(require("@svgr/core")));
1422
- const svgCode = await import_fs.default.promises.readFile(
1423
- id.replace(/\?.*$/, ""),
1424
- "utf8"
1425
- );
1426
- const componentCode = await transform2(svgCode, svgrOptions, {
1427
- filePath: id,
1428
- caller: {
1429
- previousExport: exportAsDefault ? null : code
1430
- }
1431
- });
1432
- const res = await (0, import_vite2.transformWithEsbuild)(componentCode, id, {
1433
- loader: "jsx",
1434
- ...esbuildOptions
1435
- });
1436
- return {
1437
- code: res.code,
1438
- map: null
1439
- // TODO:
1440
- };
1441
- }
1179
+ async function createAndInitializeDatabase(configManager, datalayerPort, bridgeOverride) {
1180
+ let database;
1181
+ const bridge = bridgeOverride || new import_graphql7.FilesystemBridge(configManager.rootPath, configManager.contentRootPath);
1182
+ if (configManager.hasSelfHostedConfig() && configManager.config.contentApiUrlOverride) {
1183
+ database = await configManager.loadDatabaseFile();
1184
+ database.bridge = bridge;
1185
+ } else {
1186
+ if (configManager.hasSelfHostedConfig() && !configManager.config.contentApiUrlOverride) {
1187
+ logger.warn(
1188
+ `Found a database config file at ${configManager.printRelativePath(
1189
+ configManager.selfHostedDatabaseFilePath
1190
+ )} but there was no "contentApiUrlOverride" set. Falling back to built-in datalayer`
1191
+ );
1442
1192
  }
1443
- };
1193
+ const level = new import_graphql7.TinaLevelClient(datalayerPort);
1194
+ level.openConnection();
1195
+ database = (0, import_graphql7.createDatabaseInternal)({
1196
+ bridge,
1197
+ level,
1198
+ tinaDirectory: configManager.isUsingLegacyFolder ? LEGACY_TINA_FOLDER : TINA_FOLDER
1199
+ });
1200
+ }
1201
+ return database;
1444
1202
  }
1445
1203
 
1446
- // src/next/commands/dev-command/server/index.ts
1447
- var createDevServer = async (configManager, database, searchIndex, apiURL, noWatch, databaseLock) => {
1448
- const plugins = [
1449
- transformTsxPlugin({ configManager }),
1450
- devServerEndPointsPlugin({
1451
- apiURL,
1452
- configManager,
1453
- database,
1454
- searchIndex,
1455
- databaseLock
1456
- }),
1457
- viteTransformExtension()
1458
- ];
1459
- return (0, import_vite3.createServer)(
1460
- await createConfig({
1461
- configManager,
1462
- database,
1463
- apiURL,
1464
- plugins,
1465
- noWatch,
1466
- /**
1467
- * Ensure Vite's import scan uses the spaMainPath as the input
1468
- * so it properly finds everything. This is for dev only, and when
1469
- * running the server outside of this monorepo vite fails to find
1470
- * and optimize the imports, so you get errors about it not being
1471
- * able to find an export from a module, and it's always a CJS
1472
- * module that Vite would usually transform to an ES module.
1473
- */
1474
- rollupOptions: {
1475
- input: configManager.spaMainPath,
1476
- onwarn(warning, warn) {
1477
- if (warning.code === "MODULE_LEVEL_DIRECTIVE") {
1478
- return;
1479
- }
1480
- warn(warning);
1481
- }
1482
- }
1483
- })
1484
- );
1485
- };
1486
-
1487
- // src/next/codegen/index.ts
1488
- var import_fs_extra4 = __toESM(require("fs-extra"));
1489
- var import_path4 = __toESM(require("path"));
1490
- var import_graphql6 = require("graphql");
1491
-
1492
- // src/next/codegen/codegen/index.ts
1493
- var import_graphql5 = require("graphql");
1494
-
1495
- // src/next/codegen/codegen/plugin.ts
1496
- var AddGeneratedClientFunc = (apiURL) => {
1497
- return (_schema, _documents, _config, _info) => {
1498
- return `
1499
- // TinaSDK generated code
1500
- import { createClient, TinaClient } from "tinacms/dist/client";
1204
+ // src/next/commands/baseCommands.ts
1205
+ var import_clipanion = require("clipanion");
1206
+ var import_chalk4 = __toESM(require("chalk"));
1501
1207
 
1502
- const generateRequester = (
1503
- client: TinaClient,
1504
- ) => {
1505
- const requester: (
1506
- doc: any,
1507
- vars?: any,
1508
- options?: {
1509
- branch?: string,
1510
- /**
1511
- * Aside from \`method\` and \`body\`, all fetch options are passed
1512
- * through to underlying fetch request
1513
- */
1514
- fetchOptions?: Omit<Parameters<typeof fetch>[1], 'body' | 'method'>,
1515
- },
1516
- client
1517
- ) => Promise<any> = async (doc, vars, options) => {
1518
- let url = client.apiUrl
1519
- if (options?.branch) {
1520
- const index = client.apiUrl.lastIndexOf('/')
1521
- url = client.apiUrl.substring(0, index + 1) + options.branch
1522
- }
1523
- const data = await client.request({
1524
- query: doc,
1525
- variables: vars,
1526
- url,
1527
- }, options)
1208
+ // src/utils/start-subprocess.ts
1209
+ var import_child_process = __toESM(require("child_process"));
1210
+ var startSubprocess2 = async ({ command: command2 }) => {
1211
+ if (typeof command2 === "string") {
1212
+ const commands = command2.split(" ");
1213
+ const firstCommand = commands[0];
1214
+ const args = commands.slice(1) || [];
1215
+ const ps = import_child_process.default.spawn(firstCommand, args, {
1216
+ stdio: "inherit",
1217
+ shell: true
1218
+ });
1219
+ ps.on("error", (code) => {
1220
+ logger.error(
1221
+ dangerText(
1222
+ `An error has occurred in the Next.js child process. Error message below`
1223
+ )
1224
+ );
1225
+ logger.error(`name: ${code.name}
1226
+ message: ${code.message}
1528
1227
 
1529
- return { data: data?.data, errors: data?.errors, query: doc, variables: vars || {} }
1228
+ stack: ${code.stack || "No stack was provided"}`);
1229
+ });
1230
+ ps.on("close", (code) => {
1231
+ logger.info(`child process exited with code ${code}`);
1232
+ process.exit(code);
1233
+ });
1234
+ return ps;
1530
1235
  }
1531
-
1532
- return requester
1533
- }
1534
-
1535
- /**
1536
- * @experimental this class can be used but may change in the future
1537
- **/
1538
- export const ExperimentalGetTinaClient = () =>
1539
- getSdk(
1540
- generateRequester(
1541
- createClient({
1542
- url: "${apiURL}",
1543
- queries,
1544
- })
1545
- )
1546
- )
1547
-
1548
- export const queries = (
1549
- client: TinaClient,
1550
- ) => {
1551
- const requester = generateRequester(client)
1552
- return getSdk(requester)
1553
- }
1554
- `;
1555
- };
1556
1236
  };
1557
- var AddGeneratedClient = (apiURL) => ({
1558
- plugin: AddGeneratedClientFunc(apiURL)
1559
- });
1560
-
1561
- // src/next/codegen/codegen/index.ts
1562
- var import_graphql_file_loader = require("@graphql-tools/graphql-file-loader");
1563
- var import_core = require("@graphql-codegen/core");
1564
- var import_load = require("@graphql-tools/load");
1565
- var import_typescript_operations = require("@graphql-codegen/typescript-operations");
1566
- var import_typescript = require("@graphql-codegen/typescript");
1567
-
1568
- // src/next/codegen/codegen/sdkPlugin/index.ts
1569
- var import_graphql3 = require("graphql");
1570
- var import_graphql4 = require("graphql");
1571
1237
 
1572
- // src/next/codegen/codegen/sdkPlugin/visitor.ts
1573
- var import_visitor_plugin_common = require("@graphql-codegen/visitor-plugin-common");
1574
- var import_auto_bind = __toESM(require("auto-bind"));
1575
- var import_graphql2 = require("graphql");
1576
- var GenericSdkVisitor = class extends import_visitor_plugin_common.ClientSideBaseVisitor {
1577
- constructor(schema, fragments, rawConfig) {
1578
- super(schema, fragments, rawConfig, {
1579
- usingObservableFrom: rawConfig.usingObservableFrom
1238
+ // src/next/commands/baseCommands.ts
1239
+ var import_graphql8 = require("@tinacms/graphql");
1240
+ var import_fs_extra3 = __toESM(require("fs-extra"));
1241
+ var BaseCommand = class extends import_clipanion.Command {
1242
+ constructor() {
1243
+ super(...arguments);
1244
+ this.experimentalDataLayer = import_clipanion.Option.Boolean("--experimentalData", {
1245
+ description: "DEPRECATED - Build the server with additional data querying capabilities"
1580
1246
  });
1581
- this._operationsToInclude = [];
1582
- (0, import_auto_bind.default)(this);
1583
- if (this.config.usingObservableFrom) {
1584
- this._additionalImports.push(this.config.usingObservableFrom);
1247
+ this.isomorphicGitBridge = import_clipanion.Option.Boolean("--isomorphicGitBridge", {
1248
+ description: "DEPRECATED - Enable Isomorphic Git Bridge Implementation"
1249
+ });
1250
+ this.port = import_clipanion.Option.String("-p,--port", "4001", {
1251
+ description: "Specify a port to run the server on. (default 4001)"
1252
+ });
1253
+ this.datalayerPort = import_clipanion.Option.String("--datalayer-port", "9000", {
1254
+ description: "Specify a port to run the datalayer server on. (default 9000)"
1255
+ });
1256
+ this.subCommand = import_clipanion.Option.String("-c,--command", {
1257
+ description: "The sub-command to run"
1258
+ });
1259
+ this.rootPath = import_clipanion.Option.String("--rootPath", {
1260
+ description: "Specify the root directory to run the CLI from (defaults to current working directory)"
1261
+ });
1262
+ this.verbose = import_clipanion.Option.Boolean("-v,--verbose", false, {
1263
+ description: "increase verbosity of logged output"
1264
+ });
1265
+ this.noSDK = import_clipanion.Option.Boolean("--noSDK", false, {
1266
+ description: "DEPRECATED - This should now be set in the config at client.skip = true'. Don't generate the generated client SDK"
1267
+ });
1268
+ this.noTelemetry = import_clipanion.Option.Boolean("--noTelemetry", false, {
1269
+ description: "Disable anonymous telemetry that is collected"
1270
+ });
1271
+ }
1272
+ async startSubCommand() {
1273
+ let subProc;
1274
+ if (this.subCommand) {
1275
+ subProc = await startSubprocess2({ command: this.subCommand });
1276
+ logger.info(
1277
+ `Running web application with command: ${import_chalk4.default.cyan(this.subCommand)}`
1278
+ );
1585
1279
  }
1586
- if (this.config.documentMode !== import_visitor_plugin_common.DocumentMode.string) {
1280
+ function exitHandler(options, exitCode) {
1281
+ if (subProc) {
1282
+ subProc.kill();
1283
+ }
1284
+ process.exit();
1587
1285
  }
1286
+ process.on("exit", exitHandler);
1287
+ process.on("SIGINT", exitHandler);
1288
+ process.on("SIGUSR1", exitHandler);
1289
+ process.on("SIGUSR2", exitHandler);
1290
+ process.on("uncaughtException", (error) => {
1291
+ logger.error(`Uncaught exception ${error.name}`);
1292
+ console.error(error);
1293
+ });
1588
1294
  }
1589
- buildOperation(node, documentVariableName, operationType, operationResultType, operationVariablesTypes) {
1590
- if (node.name == null) {
1591
- throw new Error(
1592
- "Plugin 'generic-sdk' cannot generate SDK for unnamed operation.\n\n" + (0, import_graphql2.print)(node)
1295
+ logDeprecationWarnings() {
1296
+ if (this.isomorphicGitBridge) {
1297
+ logger.warn("--isomorphicGitBridge has been deprecated");
1298
+ }
1299
+ if (this.experimentalDataLayer) {
1300
+ logger.warn(
1301
+ "--experimentalDataLayer has been deprecated, the data layer is now built-in automatically"
1593
1302
  );
1594
- } else {
1595
- this._operationsToInclude.push({
1596
- node,
1597
- documentVariableName,
1598
- operationType,
1599
- // This is the only line that is different
1600
- operationResultType: `{data: ${operationResultType}, errors?: { message: string, locations: { line: number, column: number }[], path: string[] }[], variables: ${operationVariablesTypes}, query: string}`,
1601
- operationVariablesTypes
1602
- });
1603
1303
  }
1604
- return null;
1605
- }
1606
- get sdkContent() {
1607
- const usingObservable = !!this.config.usingObservableFrom;
1608
- const allPossibleActions = this._operationsToInclude.map((o) => {
1609
- const optionalVariables = !o.node.variableDefinitions || o.node.variableDefinitions.length === 0 || o.node.variableDefinitions.every(
1610
- (v) => v.type.kind !== import_graphql2.Kind.NON_NULL_TYPE || v.defaultValue
1304
+ if (this.noSDK) {
1305
+ logger.warn(
1306
+ "--noSDK has been deprecated, and will be unsupported in a future release. This should be set in the config at client.skip = true"
1611
1307
  );
1612
- const returnType = usingObservable && o.operationType === "Subscription" ? "Observable" : "Promise";
1613
- return `${o.node.name.value}(variables${optionalVariables ? "?" : ""}: ${o.operationVariablesTypes}, options?: C): ${returnType}<${o.operationResultType}> {
1614
- return requester<${o.operationResultType}, ${o.operationVariablesTypes}>(${o.documentVariableName}, variables, options);
1615
- }`;
1616
- }).map((s2) => (0, import_visitor_plugin_common.indentMultiline)(s2, 2));
1617
- return `export type Requester<C= {}> = <R, V>(doc: ${this.config.documentMode === import_visitor_plugin_common.DocumentMode.string ? "string" : "DocumentNode"}, vars?: V, options?: C) => ${usingObservable ? "Promise<R> & Observable<R>" : "Promise<R>"}
1618
- export function getSdk<C>(requester: Requester<C>) {
1619
- return {
1620
- ${allPossibleActions.join(",\n")}
1621
- };
1622
- }
1623
- export type Sdk = ReturnType<typeof getSdk>;`;
1308
+ }
1624
1309
  }
1625
- };
1626
-
1627
- // src/next/codegen/codegen/sdkPlugin/index.ts
1628
- var plugin = (schema, documents, config2) => {
1629
- const allAst = (0, import_graphql4.concatAST)(
1630
- documents.reduce((prev, v) => {
1631
- return [...prev, v.document];
1632
- }, [])
1633
- );
1634
- const allFragments = [
1635
- ...allAst.definitions.filter(
1636
- (d) => d.kind === import_graphql4.Kind.FRAGMENT_DEFINITION
1637
- ).map((fragmentDef) => ({
1638
- node: fragmentDef,
1639
- name: fragmentDef.name.value,
1640
- onType: fragmentDef.typeCondition.name.value,
1641
- isExternal: false
1642
- })),
1643
- ...config2.externalFragments || []
1644
- ];
1645
- const visitor = new GenericSdkVisitor(schema, allFragments, config2);
1646
- const visitorResult = (0, import_graphql3.visit)(allAst, { leave: visitor });
1647
- return {
1648
- // We will take care of imports
1649
- // prepend: visitor.getImports(),
1650
- content: [
1651
- visitor.fragments,
1652
- ...visitorResult.definitions.filter((t) => typeof t === "string"),
1653
- visitor.sdkContent
1654
- ].join("\n")
1655
- };
1656
- };
1657
-
1658
- // src/next/codegen/codegen/index.ts
1659
- var generateTypes = async (schema, queryPathGlob = process.cwd(), fragDocPath = process.cwd(), apiURL) => {
1660
- let docs = [];
1661
- let fragDocs = [];
1662
- docs = await loadGraphQLDocuments(queryPathGlob);
1663
- fragDocs = await loadGraphQLDocuments(fragDocPath);
1664
- const res = await (0, import_core.codegen)({
1665
- // Filename is not used. This is because the typescript plugin returns a string instead of writing to a file.
1666
- filename: process.cwd(),
1667
- schema: (0, import_graphql5.parse)((0, import_graphql5.printSchema)(schema)),
1668
- documents: [...docs, ...fragDocs],
1669
- config: {},
1670
- plugins: [
1671
- { typescript: {} },
1672
- { typescriptOperations: {} },
1673
- {
1674
- typescriptSdk: {}
1675
- },
1676
- { AddGeneratedClient: {} }
1677
- ],
1678
- pluginMap: {
1679
- typescript: {
1680
- plugin: import_typescript.plugin
1681
- },
1682
- typescriptOperations: {
1683
- plugin: import_typescript_operations.plugin
1684
- },
1685
- typescriptSdk: {
1686
- plugin
1310
+ async indexContentWithSpinner({
1311
+ database,
1312
+ graphQLSchema,
1313
+ tinaSchema,
1314
+ configManager,
1315
+ partialReindex,
1316
+ text
1317
+ }) {
1318
+ const textToUse = text || "Indexing local files";
1319
+ const warnings = [];
1320
+ await spin({
1321
+ waitFor: async () => {
1322
+ var _a, _b;
1323
+ const rootPath = configManager.rootPath;
1324
+ let sha;
1325
+ try {
1326
+ sha = await (0, import_graphql8.getSha)({ fs: import_fs_extra3.default, dir: rootPath });
1327
+ } catch (e) {
1328
+ if (partialReindex) {
1329
+ console.error(
1330
+ "Failed to get sha. NOTE: `--partial-reindex` only supported for git repositories"
1331
+ );
1332
+ throw e;
1333
+ }
1334
+ }
1335
+ const lastSha = await database.getMetadata("lastSha");
1336
+ const exists = lastSha && await (0, import_graphql8.shaExists)({ fs: import_fs_extra3.default, dir: rootPath, sha: lastSha });
1337
+ let res;
1338
+ if (partialReindex && lastSha && exists && sha) {
1339
+ const pathFilter = {};
1340
+ if (configManager.isUsingLegacyFolder) {
1341
+ pathFilter[".tina/__generated__/_schema.json"] = {};
1342
+ } else {
1343
+ pathFilter["tina/tina-lock.json"] = {};
1344
+ }
1345
+ for (const collection of tinaSchema.getCollections()) {
1346
+ pathFilter[collection.path] = {
1347
+ matches: ((_a = collection.match) == null ? void 0 : _a.exclude) || ((_b = collection.match) == null ? void 0 : _b.include) ? tinaSchema.getMatches({ collection }) : void 0
1348
+ };
1349
+ }
1350
+ const { added, modified, deleted } = await (0, import_graphql8.getChangedFiles)({
1351
+ fs: import_fs_extra3.default,
1352
+ dir: rootPath,
1353
+ from: lastSha,
1354
+ to: sha,
1355
+ pathFilter
1356
+ });
1357
+ const tinaPathUpdates = modified.filter(
1358
+ (path14) => path14.startsWith(".tina/__generated__/_schema.json") || path14.startsWith("tina/tina-lock.json")
1359
+ );
1360
+ if (tinaPathUpdates.length > 0) {
1361
+ res = await database.indexContent({
1362
+ graphQLSchema,
1363
+ tinaSchema
1364
+ });
1365
+ } else {
1366
+ if (added.length > 0 || modified.length > 0) {
1367
+ await database.indexContentByPaths([...added, ...modified]);
1368
+ }
1369
+ if (deleted.length > 0) {
1370
+ await database.deleteContentByPaths(deleted);
1371
+ }
1372
+ }
1373
+ } else {
1374
+ res = await database.indexContent({
1375
+ graphQLSchema,
1376
+ tinaSchema
1377
+ });
1378
+ }
1379
+ if (sha) {
1380
+ await database.setMetadata("lastSha", sha);
1381
+ }
1382
+ if (res == null ? void 0 : res.warnings) {
1383
+ warnings.push(...res.warnings);
1384
+ }
1687
1385
  },
1688
- AddGeneratedClient: AddGeneratedClient(apiURL)
1689
- }
1690
- });
1691
- return res;
1692
- };
1693
- var loadGraphQLDocuments = async (globPath) => {
1694
- let result = [];
1695
- try {
1696
- result = await (0, import_load.loadDocuments)(globPath, {
1697
- loaders: [new import_graphql_file_loader.GraphQLFileLoader()]
1386
+ text: textToUse
1698
1387
  });
1699
- } catch (e) {
1700
- if (
1701
- // https://www.graphql-tools.com/docs/documents-loading#no-files-found
1702
- (e.message || "").includes(
1703
- "Unable to find any GraphQL type definitions for the following pointers:"
1704
- )
1705
- ) {
1706
- } else {
1707
- throw e;
1388
+ if (warnings.length > 0) {
1389
+ logger.warn(`Indexing completed with ${warnings.length} warning(s)`);
1390
+ warnings.forEach((warning) => {
1391
+ logger.warn(warnText(`${warning}`));
1392
+ });
1708
1393
  }
1709
1394
  }
1710
- return result;
1711
1395
  };
1712
1396
 
1713
- // src/next/codegen/index.ts
1714
- var import_esbuild2 = require("esbuild");
1715
- var import_graphql7 = require("@tinacms/graphql");
1716
- var import_normalize_path3 = __toESM(require("normalize-path"));
1717
- var TINA_HOST = "content.tinajs.io";
1718
- var Codegen = class {
1719
- constructor({
1720
- configManager,
1721
- port,
1722
- queryDoc,
1723
- fragDoc,
1724
- isLocal,
1725
- graphqlSchemaDoc,
1726
- tinaSchema,
1727
- lookup,
1728
- noClientBuildCache
1729
- }) {
1730
- this.isLocal = isLocal;
1731
- this.graphqlSchemaDoc = graphqlSchemaDoc;
1732
- this.configManager = configManager;
1733
- this.port = port;
1734
- this.schema = (0, import_graphql6.buildASTSchema)(graphqlSchemaDoc);
1735
- this.tinaSchema = tinaSchema;
1736
- this.queryDoc = queryDoc;
1737
- this.fragDoc = fragDoc;
1738
- this.lookup = lookup;
1739
- this.noClientBuildCache = noClientBuildCache;
1740
- }
1741
- async writeConfigFile(fileName, data) {
1742
- const filePath = import_path4.default.join(
1743
- this.configManager.generatedFolderPath,
1744
- fileName
1745
- );
1746
- await import_fs_extra4.default.ensureFile(filePath);
1747
- await import_fs_extra4.default.outputFile(filePath, data);
1748
- if (this.configManager.hasSeparateContentRoot()) {
1749
- const filePath2 = import_path4.default.join(
1750
- this.configManager.generatedFolderPathContentRepo,
1751
- fileName
1752
- );
1753
- await import_fs_extra4.default.ensureFile(filePath2);
1754
- await import_fs_extra4.default.outputFile(filePath2, data);
1755
- }
1756
- }
1757
- async removeGeneratedFilesIfExists() {
1758
- await unlinkIfExists(this.configManager.generatedClientJSFilePath);
1759
- await unlinkIfExists(this.configManager.generatedTypesDFilePath);
1760
- await unlinkIfExists(this.configManager.generatedTypesJSFilePath);
1761
- await unlinkIfExists(this.configManager.generatedTypesTSFilePath);
1762
- await unlinkIfExists(this.configManager.generatedClientTSFilePath);
1763
- await unlinkIfExists(this.configManager.generatedQueriesFilePath);
1764
- await unlinkIfExists(this.configManager.generatedFragmentsFilePath);
1397
+ // src/next/commands/dev-command/html.ts
1398
+ var errorHTML = `<style type="text/css">
1399
+ #no-assets-placeholder body {
1400
+ font-family: sans-serif;
1401
+ font-size: 16px;
1402
+ line-height: 1.4;
1403
+ color: #333;
1404
+ background-color: #f5f5f5;
1405
+ }
1406
+ #no-assets-placeholder {
1407
+ max-width: 600px;
1408
+ margin: 0 auto;
1409
+ padding: 40px;
1410
+ text-align: center;
1411
+ background-color: #fff;
1412
+ box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1);
1413
+ }
1414
+ #no-assets-placeholder h1 {
1415
+ font-size: 24px;
1416
+ margin-bottom: 20px;
1417
+ }
1418
+ #no-assets-placeholder p {
1419
+ margin-bottom: 10px;
1420
+ }
1421
+ #no-assets-placeholder a {
1422
+ color: #0077cc;
1423
+ text-decoration: none;
1424
+ }
1425
+ #no-assets-placeholder a:hover {
1426
+ text-decoration: underline;
1427
+ }
1428
+ </style>
1429
+ <div id="no-assets-placeholder">
1430
+ <h1>Failed loading TinaCMS assets</h1>
1431
+ <p>
1432
+ Your TinaCMS configuration may be misconfigured, and we could not load
1433
+ the assets for this page.
1434
+ </p>
1435
+ <p>
1436
+ Please visit <a href="https://tina.io/docs/tina-cloud/faq/#how-do-i-resolve-failed-loading-tinacms-assets-error">this doc</a> for help.
1437
+ </p>
1438
+ </div>
1439
+ </div>`.trim().replace(/[\r\n\s]+/g, " ");
1440
+ var devHTML = (port) => `<!DOCTYPE html>
1441
+ <html lang="en">
1442
+ <head>
1443
+ <meta charset="UTF-8" />
1444
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
1445
+ <title>TinaCMS</title>
1446
+ </head>
1447
+
1448
+ <!-- if development -->
1449
+ <script type="module">
1450
+ import RefreshRuntime from 'http://localhost:${port}/@react-refresh'
1451
+ RefreshRuntime.injectIntoGlobalHook(window)
1452
+ window.$RefreshReg$ = () => {}
1453
+ window.$RefreshSig$ = () => (type) => type
1454
+ window.__vite_plugin_react_preamble_installed__ = true
1455
+ </script>
1456
+ <script type="module" src="http://localhost:${port}/@vite/client"></script>
1457
+ <script>
1458
+ function handleLoadError() {
1459
+ // Assets have failed to load
1460
+ document.getElementById('root').innerHTML = '${errorHTML}';
1765
1461
  }
1766
- async execute() {
1767
- await this.writeConfigFile(
1768
- "_graphql.json",
1769
- JSON.stringify(this.graphqlSchemaDoc)
1770
- );
1771
- const { search, ...rest } = this.tinaSchema.schema.config;
1772
- this.tinaSchema.schema.config = rest;
1773
- await this.writeConfigFile(
1774
- "_schema.json",
1775
- JSON.stringify(this.tinaSchema.schema)
1776
- );
1777
- await this.writeConfigFile("_lookup.json", JSON.stringify(this.lookup));
1778
- const { apiURL, localUrl, tinaCloudUrl } = this._createApiUrl();
1779
- this.apiURL = apiURL;
1780
- this.localUrl = localUrl;
1781
- this.productionUrl = tinaCloudUrl;
1782
- if (this.configManager.shouldSkipSDK()) {
1783
- await this.removeGeneratedFilesIfExists();
1784
- return apiURL;
1785
- }
1786
- await import_fs_extra4.default.outputFile(
1787
- this.configManager.generatedQueriesFilePath,
1788
- this.queryDoc
1789
- );
1790
- await import_fs_extra4.default.outputFile(
1791
- this.configManager.generatedFragmentsFilePath,
1792
- this.fragDoc
1793
- );
1794
- await maybeWarnFragmentSize(this.configManager.generatedFragmentsFilePath);
1795
- const { clientString } = await this.genClient();
1796
- const databaseClientString = this.configManager.hasSelfHostedConfig() ? await this.genDatabaseClient() : "";
1797
- const { codeString, schemaString } = await this.genTypes();
1798
- await import_fs_extra4.default.outputFile(
1799
- this.configManager.generatedGraphQLGQLPath,
1800
- schemaString
1801
- );
1802
- if (this.configManager.isUsingTs()) {
1803
- await import_fs_extra4.default.outputFile(
1804
- this.configManager.generatedTypesTSFilePath,
1805
- codeString
1806
- );
1807
- await import_fs_extra4.default.outputFile(
1808
- this.configManager.generatedClientTSFilePath,
1809
- clientString
1810
- );
1811
- if (this.configManager.hasSelfHostedConfig()) {
1812
- await import_fs_extra4.default.outputFile(
1813
- this.configManager.generatedDatabaseClientTSFilePath,
1814
- databaseClientString
1815
- );
1816
- }
1817
- await unlinkIfExists(this.configManager.generatedClientJSFilePath);
1818
- await unlinkIfExists(this.configManager.generatedTypesDFilePath);
1819
- await unlinkIfExists(this.configManager.generatedTypesJSFilePath);
1820
- } else {
1821
- await import_fs_extra4.default.outputFile(
1822
- this.configManager.generatedTypesDFilePath,
1823
- codeString
1824
- );
1825
- const jsTypes = await (0, import_esbuild2.transform)(codeString, { loader: "ts" });
1826
- await import_fs_extra4.default.outputFile(
1827
- this.configManager.generatedTypesJSFilePath,
1828
- jsTypes.code
1829
- );
1830
- await import_fs_extra4.default.outputFile(
1831
- this.configManager.generatedClientDFilePath,
1832
- clientString
1833
- );
1834
- const jsClient = await (0, import_esbuild2.transform)(clientString, { loader: "ts" });
1835
- await import_fs_extra4.default.outputFile(
1836
- this.configManager.generatedClientJSFilePath,
1837
- jsClient.code
1838
- );
1839
- await unlinkIfExists(this.configManager.generatedTypesTSFilePath);
1840
- await unlinkIfExists(this.configManager.generatedClientTSFilePath);
1841
- if (this.configManager.hasSelfHostedConfig()) {
1842
- const jsDatabaseClient = await (0, import_esbuild2.transform)(databaseClientString, {
1843
- loader: "ts"
1844
- });
1845
- await import_fs_extra4.default.outputFile(
1846
- this.configManager.generatedDatabaseClientJSFilePath,
1847
- jsDatabaseClient.code
1848
- );
1849
- await import_fs_extra4.default.outputFile(
1850
- this.configManager.generatedDatabaseClientDFilePath,
1851
- databaseClientString
1852
- );
1853
- await unlinkIfExists(
1854
- this.configManager.generatedDatabaseClientTSFilePath
1855
- );
1856
- }
1857
- }
1858
- return apiURL;
1859
- }
1860
- _createApiUrl() {
1861
- var _a, _b, _c, _d;
1862
- const branch = (_a = this.configManager.config) == null ? void 0 : _a.branch;
1863
- const clientId = (_b = this.configManager.config) == null ? void 0 : _b.clientId;
1864
- const token = (_c = this.configManager.config) == null ? void 0 : _c.token;
1865
- const fullVersion = this.configManager.getTinaGraphQLVersion();
1866
- const version2 = `${fullVersion.major}.${fullVersion.minor}`;
1867
- const baseUrl = ((_d = this.configManager.config.tinaioConfig) == null ? void 0 : _d.contentApiUrlOverride) || `https://${TINA_HOST}`;
1868
- if ((!branch || !clientId || !token) && !this.port && !this.configManager.config.contentApiUrlOverride) {
1869
- const missing = [];
1870
- if (!branch) missing.push("branch");
1871
- if (!clientId) missing.push("clientId");
1872
- if (!token) missing.push("token");
1873
- throw new Error(
1874
- `Client not configured properly. Missing ${missing.join(
1875
- ", "
1876
- )}. Please visit https://tina.io/docs/tina-cloud/overview for more information`
1877
- );
1878
- }
1879
- let localUrl = `http://localhost:${this.port}/graphql`;
1880
- let tinaCloudUrl = `${baseUrl}/${version2}/content/${clientId}/github/${branch}`;
1881
- let apiURL = this.isLocal ? `http://localhost:${this.port}/graphql` : `${baseUrl}/${version2}/content/${clientId}/github/${branch}`;
1882
- if (this.configManager.config.contentApiUrlOverride) {
1883
- apiURL = this.configManager.config.contentApiUrlOverride;
1884
- localUrl = apiURL;
1885
- tinaCloudUrl = apiURL;
1886
- }
1887
- return { apiURL, localUrl, tinaCloudUrl };
1888
- }
1889
- getApiURL() {
1890
- if (!this.apiURL)
1891
- throw new Error("apiURL not set. Please run execute() first");
1892
- return this.apiURL;
1893
- }
1894
- async genDatabaseClient() {
1895
- var _a, _b;
1896
- const authCollection = this.tinaSchema.getCollections().find((c) => c.isAuthCollection);
1897
- let authFields = [];
1898
- if (authCollection) {
1899
- const usersFields = (0, import_graphql7.mapUserFields)(authCollection, []);
1900
- if (usersFields.length === 0) {
1901
- throw new Error("No user field found");
1902
- }
1903
- if (usersFields.length > 1) {
1904
- throw new Error("Only one user field is allowed");
1905
- }
1906
- authFields = (_b = (_a = usersFields[0]) == null ? void 0 : _a.collectable) == null ? void 0 : _b.fields.map((f) => {
1907
- if (f.type !== "password" && f.type !== "object") {
1908
- if (f.uid) {
1909
- return `id:${f.name}`;
1910
- } else {
1911
- return `${f.name}`;
1912
- }
1913
- } else if (f.type === "password") {
1914
- return `_password: ${f.name} { passwordChangeRequired }`;
1915
- }
1916
- });
1917
- }
1918
- return `// @ts-nocheck
1919
- import { resolve } from "@tinacms/datalayer";
1920
- import type { TinaClient } from "tinacms/dist/client";
1921
-
1922
- import { queries } from "./types";
1923
- import database from "../database";
1924
-
1925
- export async function databaseRequest({ query, variables, user }) {
1926
- const result = await resolve({
1927
- config: {
1928
- useRelativeMedia: true,
1929
- },
1930
- database,
1931
- query,
1932
- variables,
1933
- verbose: true,
1934
- ctxUser: user,
1935
- });
1936
-
1937
- return result;
1938
- }
1939
-
1940
- export async function authenticate({ username, password }) {
1941
- return databaseRequest({
1942
- query: \`query auth($username:String!, $password:String!) {
1943
- authenticate(sub:$username, password:$password) {
1944
- ${authFields.join(" ")}
1945
- }
1946
- }\`,
1947
- variables: { username, password },
1948
- })
1949
- }
1950
-
1951
- export async function authorize(user: { sub: string }) {
1952
- return databaseRequest({
1953
- query: \`query authz { authorize { ${authFields.join(" ")}} }\`,
1954
- variables: {},
1955
- user
1956
- })
1957
- }
1958
-
1959
- function createDatabaseClient<GenQueries = Record<string, unknown>>({
1960
- queries,
1961
- }: {
1962
- queries: (client: {
1963
- request: TinaClient<GenQueries>["request"];
1964
- }) => GenQueries;
1965
- }) {
1966
- const request = async ({ query, variables, user }) => {
1967
- const data = await databaseRequest({ query, variables, user });
1968
- return { data: data.data as any, query, variables, errors: data.errors || null };
1969
- };
1970
- const q = queries({
1971
- request,
1972
- });
1973
- return { queries: q, request, authenticate, authorize };
1974
- }
1462
+ </script>
1463
+ <script
1464
+ type="module"
1465
+ src="http://localhost:${port}/src/main.tsx"
1466
+ onerror="handleLoadError()"
1467
+ ></script>
1468
+ <body class="tina-tailwind">
1469
+ <div id="root"></div>
1470
+ </body>
1471
+ </html>`;
1975
1472
 
1976
- export const databaseClient = createDatabaseClient({ queries });
1473
+ // src/next/commands/dev-command/server/index.ts
1474
+ var import_vite3 = require("vite");
1977
1475
 
1978
- export const client = databaseClient;
1476
+ // src/next/vite/index.ts
1477
+ var import_node_path2 = __toESM(require("path"));
1478
+ var import_plugin_react = __toESM(require("@vitejs/plugin-react"));
1479
+ var import_fs_extra4 = __toESM(require("fs-extra"));
1480
+ var import_normalize_path3 = __toESM(require("normalize-path"));
1481
+ var import_vite = require("vite");
1979
1482
 
1980
- export default databaseClient;
1981
- `;
1982
- }
1983
- async genClient() {
1984
- var _a, _b, _c;
1985
- const token = (_a = this.configManager.config) == null ? void 0 : _a.token;
1986
- const errorPolicy = (_c = (_b = this.configManager.config) == null ? void 0 : _b.client) == null ? void 0 : _c.errorPolicy;
1987
- const apiURL = this.getApiURL();
1988
- const clientString = `import { createClient } from "tinacms/dist/client";
1989
- import { queries } from "./types";
1990
- export const client = createClient({ ${this.noClientBuildCache === false ? `cacheDir: '${(0, import_normalize_path3.default)(
1991
- this.configManager.generatedCachePath
1992
- )}', ` : ""}url: '${apiURL}', token: '${token}', queries, ${errorPolicy ? `errorPolicy: '${errorPolicy}'` : ""} });
1993
- export default client;
1994
- `;
1995
- return { apiURL, clientString };
1996
- }
1997
- async genTypes() {
1998
- const typescriptTypes = await generateTypes(
1999
- this.schema,
2000
- this.configManager.userQueriesAndFragmentsGlob,
2001
- this.configManager.generatedQueriesAndFragmentsGlob,
2002
- this.getApiURL()
2003
- );
2004
- const codeString = `//@ts-nocheck
2005
- // DO NOT MODIFY THIS FILE. This file is automatically generated by Tina
2006
- export function gql(strings: TemplateStringsArray, ...args: string[]): string {
2007
- let str = ''
2008
- strings.forEach((string, i) => {
2009
- str += string + (args[i] || '')
2010
- })
2011
- return str
2012
- }
2013
- ${typescriptTypes}
2014
- `;
2015
- const schemaString = `# DO NOT MODIFY THIS FILE. This file is automatically generated by Tina
2016
- ${(0, import_graphql6.printSchema)(this.schema)}
2017
- schema {
2018
- query: Query
2019
- mutation: Mutation
2020
- }
2021
- `;
2022
- return { codeString, schemaString };
2023
- }
2024
- };
2025
- var maybeWarnFragmentSize = async (filepath) => {
2026
- if (
2027
- // is the file bigger than 100kb?
2028
- (await import_fs_extra4.default.stat(filepath)).size > // convert to 100 kb to bytes
2029
- 100 * 1024
2030
- ) {
2031
- console.warn(
2032
- "Warning: frags.gql is very large (>100kb). Consider setting the reference depth to 1 or 0. See code snippet below."
2033
- );
2034
- console.log(
2035
- `const schema = defineSchema({
2036
- client: {
2037
- referenceDepth: 1,
2038
- },
2039
- // ...
2040
- })`
2041
- );
2042
- }
2043
- };
2044
- var unlinkIfExists = async (filepath) => {
2045
- if (import_fs_extra4.default.existsSync(filepath)) {
2046
- import_fs_extra4.default.unlinkSync(filepath);
2047
- }
2048
- };
2049
-
2050
- // src/next/database.ts
2051
- var import_graphql8 = require("@tinacms/graphql");
2052
- var import_readable_stream = require("readable-stream");
2053
- var import_net = require("net");
2054
- var import_many_level = require("many-level");
2055
- var import_memory_level = require("memory-level");
2056
- var createDBServer = (port) => {
2057
- const levelHost = new import_many_level.ManyLevelHost(
1483
+ // src/next/vite/tailwind.ts
1484
+ var import_node_path = __toESM(require("path"));
1485
+ var import_aspect_ratio = __toESM(require("@tailwindcss/aspect-ratio"));
1486
+ var import_container_queries = __toESM(require("@tailwindcss/container-queries"));
1487
+ var import_typography = __toESM(require("@tailwindcss/typography"));
1488
+ var import_tailwindcss = __toESM(require("tailwindcss"));
1489
+ var import_defaultTheme = __toESM(require("tailwindcss/defaultTheme.js"));
1490
+ var tinaTailwind = (spaPath, prebuildFilePath) => {
1491
+ return {
1492
+ name: "vite-plugin-tina",
2058
1493
  // @ts-ignore
2059
- new import_memory_level.MemoryLevel({
2060
- valueEncoding: "json"
2061
- })
2062
- );
2063
- const dbServer = (0, import_net.createServer)(function(socket) {
2064
- return (0, import_readable_stream.pipeline)(socket, levelHost.createRpcStream(), socket, () => {
2065
- });
2066
- });
2067
- dbServer.once("error", (err) => {
2068
- if ((err == null ? void 0 : err.code) === "EADDRINUSE") {
2069
- throw new Error(
2070
- `Tina Dev server is already in use. Datalayer server is busy on port ${port}`
2071
- );
2072
- }
2073
- });
2074
- dbServer.listen(port);
2075
- };
2076
- async function createAndInitializeDatabase(configManager, datalayerPort, bridgeOverride) {
2077
- let database;
2078
- const bridge = bridgeOverride || new import_graphql8.FilesystemBridge(configManager.rootPath, configManager.contentRootPath);
2079
- if (configManager.hasSelfHostedConfig() && configManager.config.contentApiUrlOverride) {
2080
- database = await configManager.loadDatabaseFile();
2081
- database.bridge = bridge;
2082
- } else {
2083
- if (configManager.hasSelfHostedConfig() && !configManager.config.contentApiUrlOverride) {
2084
- logger.warn(
2085
- `Found a database config file at ${configManager.printRelativePath(
2086
- configManager.selfHostedDatabaseFilePath
2087
- )} but there was no "contentApiUrlOverride" set. Falling back to built-in datalayer`
2088
- );
2089
- }
2090
- const level = new import_graphql8.TinaLevelClient(datalayerPort);
2091
- level.openConnection();
2092
- database = (0, import_graphql8.createDatabaseInternal)({
2093
- bridge,
2094
- level,
2095
- tinaDirectory: configManager.isUsingLegacyFolder ? LEGACY_TINA_FOLDER : TINA_FOLDER
2096
- });
2097
- }
2098
- return database;
2099
- }
2100
-
2101
- // src/next/commands/baseCommands.ts
2102
- var import_clipanion = require("clipanion");
2103
- var import_chalk4 = __toESM(require("chalk"));
2104
-
2105
- // src/utils/start-subprocess.ts
2106
- var import_child_process = __toESM(require("child_process"));
2107
- var startSubprocess2 = async ({ command: command2 }) => {
2108
- if (typeof command2 === "string") {
2109
- const commands = command2.split(" ");
2110
- const firstCommand = commands[0];
2111
- const args = commands.slice(1) || [];
2112
- const ps = import_child_process.default.spawn(firstCommand, args, {
2113
- stdio: "inherit",
2114
- shell: true
2115
- });
2116
- ps.on("error", (code) => {
2117
- logger.error(
2118
- dangerText(
2119
- `An error has occurred in the Next.js child process. Error message below`
2120
- )
2121
- );
2122
- logger.error(`name: ${code.name}
2123
- message: ${code.message}
2124
-
2125
- stack: ${code.stack || "No stack was provided"}`);
2126
- });
2127
- ps.on("close", (code) => {
2128
- logger.info(`child process exited with code ${code}`);
2129
- process.exit(code);
2130
- });
2131
- return ps;
2132
- }
1494
+ config: (viteConfig) => {
1495
+ const plugins = [];
1496
+ const content = [
1497
+ import_node_path.default.join(spaPath, "src/**/*.{vue,js,ts,jsx,tsx,svelte}"),
1498
+ prebuildFilePath,
1499
+ require.resolve("tinacms")
1500
+ ];
1501
+ const tw = (0, import_tailwindcss.default)({
1502
+ theme: {
1503
+ columns: {
1504
+ auto: "auto",
1505
+ 1: "1",
1506
+ 2: "2",
1507
+ 3: "3",
1508
+ 4: "4",
1509
+ 5: "5",
1510
+ 6: "6",
1511
+ 7: "7",
1512
+ 8: "8",
1513
+ 9: "9",
1514
+ 10: "10",
1515
+ 11: "11",
1516
+ 12: "12",
1517
+ "3xs": "256px",
1518
+ "2xs": "288px",
1519
+ xs: "320px",
1520
+ sm: "384px",
1521
+ md: "448px",
1522
+ lg: "512px",
1523
+ xl: "576px",
1524
+ "2xl": "672px",
1525
+ "3xl": "768px",
1526
+ "4xl": "896px",
1527
+ "5xl": "1024px",
1528
+ "6xl": "1152px",
1529
+ "7xl": "1280px"
1530
+ },
1531
+ spacing: {
1532
+ px: "1px",
1533
+ 0: "0px",
1534
+ 0.5: "2px",
1535
+ 1: "4px",
1536
+ 1.5: "6px",
1537
+ 2: "8px",
1538
+ 2.5: "10px",
1539
+ 3: "12px",
1540
+ 3.5: "14px",
1541
+ 4: "16px",
1542
+ 5: "20px",
1543
+ 6: "24px",
1544
+ 7: "28px",
1545
+ 8: "32px",
1546
+ 9: "36px",
1547
+ 10: "40px",
1548
+ 11: "44px",
1549
+ 12: "48px",
1550
+ 14: "56px",
1551
+ 16: "64px",
1552
+ 18: "72px",
1553
+ 20: "80px",
1554
+ 24: "96px",
1555
+ 28: "114px",
1556
+ 32: "128px",
1557
+ 36: "144px",
1558
+ 40: "160px",
1559
+ 44: "176px",
1560
+ 48: "192px",
1561
+ 52: "208px",
1562
+ 56: "224px",
1563
+ 60: "240px",
1564
+ 64: "256px",
1565
+ 72: "288px",
1566
+ 80: "320px",
1567
+ 96: "384px"
1568
+ },
1569
+ borderRadius: {
1570
+ none: "0px",
1571
+ sm: "2px",
1572
+ DEFAULT: "4px",
1573
+ md: "6px",
1574
+ lg: "8px",
1575
+ xl: "12px",
1576
+ "2xl": "16px",
1577
+ "3xl": "24px",
1578
+ full: "9999px"
1579
+ },
1580
+ borderWidth: {
1581
+ DEFAULT: "1px",
1582
+ 0: "0",
1583
+ 2: "2px",
1584
+ 3: "3px",
1585
+ 4: "4px",
1586
+ 6: "6px",
1587
+ 8: "8px"
1588
+ },
1589
+ fontSize: {
1590
+ xs: ["13px", { lineHeight: "1.33" }],
1591
+ sm: ["14px", { lineHeight: "1.43" }],
1592
+ base: ["16px", { lineHeight: "1.5" }],
1593
+ md: ["16px", { lineHeight: "1.5" }],
1594
+ lg: ["18px", { lineHeight: "1.55" }],
1595
+ xl: ["20px", { lineHeight: "1.4" }],
1596
+ "2xl": ["24px", { lineHeight: "1.33" }],
1597
+ "3xl": ["30px", { lineHeight: "1.2" }],
1598
+ "4xl": ["36px", { lineHeight: "1.1" }],
1599
+ "5xl": ["48px", { lineHeight: "1" }],
1600
+ "6xl": ["60px", { lineHeight: "1" }],
1601
+ "7xl": ["72px", { lineHeight: "1" }],
1602
+ "8xl": ["96px", { lineHeight: "1" }],
1603
+ "9xl": ["128px", { lineHeight: "1" }]
1604
+ },
1605
+ opacity: {
1606
+ 0: "0",
1607
+ 5: ".05",
1608
+ 7: ".07",
1609
+ 10: ".1",
1610
+ 15: ".15",
1611
+ 20: ".2",
1612
+ 25: ".25",
1613
+ 30: ".3",
1614
+ 40: ".4",
1615
+ 50: ".5",
1616
+ 60: ".6",
1617
+ 70: ".7",
1618
+ 75: ".75",
1619
+ 80: ".8",
1620
+ 90: ".9",
1621
+ 100: "1"
1622
+ },
1623
+ zIndex: {
1624
+ "-1": "-1",
1625
+ base: "9000",
1626
+ panel: "9400",
1627
+ menu: "9800",
1628
+ chrome: "10200",
1629
+ overlay: "10600",
1630
+ modal: "10800",
1631
+ 0: "0",
1632
+ 10: "10",
1633
+ 20: "20",
1634
+ 30: "30",
1635
+ 40: "40",
1636
+ 25: "25",
1637
+ 50: "50",
1638
+ 75: "75",
1639
+ 100: "100",
1640
+ auto: "auto"
1641
+ },
1642
+ extend: {
1643
+ scale: {
1644
+ 97: ".97",
1645
+ 103: "1.03"
1646
+ },
1647
+ transitionDuration: {
1648
+ 0: "0ms",
1649
+ 2e3: "2000ms"
1650
+ },
1651
+ boxShadow: {
1652
+ xs: "0 0 0 1px rgba(0, 0, 0, 0.05)",
1653
+ outline: "0 0 0 3px rgba(66, 153, 225, 0.5)"
1654
+ },
1655
+ colors: {
1656
+ blue: {
1657
+ 50: "#DCEEFF",
1658
+ 100: "#B4DBFF",
1659
+ 200: "#85C5FE",
1660
+ 300: "#4EABFE",
1661
+ 400: "#2296fe",
1662
+ 500: "#0084FF",
1663
+ 600: "#0574e4",
1664
+ 700: "#0D5DBD",
1665
+ 800: "#144696",
1666
+ 900: "#1D2C6C",
1667
+ 1e3: "#241748"
1668
+ },
1669
+ gray: {
1670
+ 50: "#F6F6F9",
1671
+ 100: "#EDECF3",
1672
+ 150: "#E6E3EF",
1673
+ 200: "#E1DDEC",
1674
+ 250: "#C9C5D5",
1675
+ 300: "#b2adbe",
1676
+ 400: "#918c9e",
1677
+ 500: "#716c7f",
1678
+ 600: "#565165",
1679
+ 700: "#433e52",
1680
+ 800: "#363145",
1681
+ 900: "#252336",
1682
+ 1e3: "#1c1b2e"
1683
+ },
1684
+ orange: {
1685
+ 400: "#EB6337",
1686
+ 500: "#EC4815",
1687
+ 600: "#DC4419"
1688
+ },
1689
+ background: "#FFFFFF",
1690
+ foreground: "#0A0A0A",
1691
+ muted: "#F5F5F5",
1692
+ "muted-foreground": "#737373",
1693
+ popover: "#FFFFFF",
1694
+ "popover-foreground": "#0A0A0A",
1695
+ card: "#FFFFFF",
1696
+ "card-foreground": "#0A0A0A",
1697
+ border: "#E5E5E5",
1698
+ input: "#E5E5E5",
1699
+ primary: "#171717",
1700
+ "primary-foreground": "#FAFAFA",
1701
+ secondary: "#F5F5F5",
1702
+ "secondary-foreground": "#171717",
1703
+ accent: "#F5F5F5",
1704
+ "accent-foreground": "#171717",
1705
+ destructive: "#FF3B3B",
1706
+ "destructive-foreground": "#FAFAFA",
1707
+ ring: "#0A0A0A"
1708
+ },
1709
+ fontFamily: {
1710
+ sans: ["Inter", ...import_defaultTheme.default.fontFamily.sans]
1711
+ },
1712
+ lineHeight: {
1713
+ 3: "12px",
1714
+ 4: "16px",
1715
+ 5: "20px",
1716
+ 6: "24px",
1717
+ 7: "28px",
1718
+ 8: "32px",
1719
+ 9: "36px",
1720
+ 10: "40px"
1721
+ },
1722
+ maxWidth: {
1723
+ form: "900px"
1724
+ },
1725
+ screens: {
1726
+ xs: "320px",
1727
+ sm: "560px",
1728
+ md: "720px",
1729
+ lg: "1030px"
1730
+ }
1731
+ }
1732
+ },
1733
+ content,
1734
+ plugins: [
1735
+ (0, import_typography.default)({ className: "tina-prose" }),
1736
+ import_aspect_ratio.default,
1737
+ import_container_queries.default
1738
+ ]
1739
+ });
1740
+ plugins.push(tw);
1741
+ return {
1742
+ css: {
1743
+ postcss: {
1744
+ plugins
1745
+ }
1746
+ }
1747
+ };
1748
+ }
1749
+ };
2133
1750
  };
2134
1751
 
2135
- // src/utils/spinner.ts
2136
- var import_cli_spinner = require("cli-spinner");
2137
- async function localSpin({
2138
- waitFor,
2139
- text
1752
+ // src/next/vite/index.ts
1753
+ async function listFilesRecursively({
1754
+ directoryPath,
1755
+ config: config2,
1756
+ roothPath
2140
1757
  }) {
2141
- const spinner = new import_cli_spinner.Spinner({
2142
- text: `${text} %s`,
2143
- stream: process.stderr,
2144
- onTick: function(msg) {
2145
- this.clearLine(this.stream);
2146
- this.stream.write(msg);
1758
+ const fullDirectoryPath = import_node_path2.default.join(
1759
+ roothPath,
1760
+ config2.publicFolder,
1761
+ directoryPath
1762
+ );
1763
+ const exists = await import_fs_extra4.default.pathExists(fullDirectoryPath);
1764
+ if (!exists) {
1765
+ return { "0": [] };
1766
+ }
1767
+ const items = await import_fs_extra4.default.readdir(fullDirectoryPath);
1768
+ const staticMediaItems = [];
1769
+ for (const item of items) {
1770
+ const itemPath = import_node_path2.default.join(fullDirectoryPath, item);
1771
+ const stats = await import_fs_extra4.default.promises.lstat(itemPath);
1772
+ const staticMediaItem = {
1773
+ id: item,
1774
+ filename: item,
1775
+ type: stats.isDirectory() ? "dir" : "file",
1776
+ directory: `${directoryPath.replace(config2.mediaRoot, "")}`,
1777
+ src: `/${import_node_path2.default.join(directoryPath, item)}`,
1778
+ thumbnails: {
1779
+ "75x75": `/${import_node_path2.default.join(directoryPath, item)}`,
1780
+ "400x400": `/${import_node_path2.default.join(directoryPath, item)}`,
1781
+ "1000x1000": `/${import_node_path2.default.join(directoryPath, item)}`
1782
+ }
1783
+ };
1784
+ if (stats.isDirectory()) {
1785
+ staticMediaItem.children = await listFilesRecursively({
1786
+ directoryPath: import_node_path2.default.join(directoryPath, item),
1787
+ config: config2,
1788
+ roothPath
1789
+ });
2147
1790
  }
2148
- });
2149
- spinner.setSpinnerString("\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827\u2807\u280F");
2150
- spinner.start();
2151
- const res = await waitFor();
2152
- spinner.stop();
2153
- console.log("");
2154
- return res;
1791
+ staticMediaItems.push(staticMediaItem);
1792
+ }
1793
+ function chunkArrayIntoObject(array, chunkSize) {
1794
+ const result = {};
1795
+ for (let i = 0; i < array.length; i += chunkSize) {
1796
+ const chunkKey = `${i / chunkSize * 20}`;
1797
+ result[chunkKey] = array.slice(i, i + chunkSize);
1798
+ }
1799
+ return result;
1800
+ }
1801
+ return chunkArrayIntoObject(staticMediaItems, 20);
2155
1802
  }
2156
- function spin({
2157
- waitFor,
2158
- text
2159
- }) {
2160
- if (process.env.CI) {
2161
- console.log(text);
2162
- return waitFor();
2163
- } else {
2164
- return localSpin({
2165
- text,
2166
- waitFor
1803
+ var createConfig = async ({
1804
+ configManager,
1805
+ apiURL,
1806
+ plugins = [],
1807
+ noWatch,
1808
+ rollupOptions
1809
+ }) => {
1810
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1811
+ const publicEnv = {};
1812
+ Object.keys(process.env).forEach((key) => {
1813
+ if (key.startsWith("TINA_PUBLIC_") || key.startsWith("NEXT_PUBLIC_") || key === "NODE_ENV" || key === "HEAD") {
1814
+ try {
1815
+ if (typeof process.env[key] === "string") {
1816
+ publicEnv[key] = process.env[key];
1817
+ } else {
1818
+ publicEnv[key] = JSON.stringify(process.env[key]);
1819
+ }
1820
+ } catch (error) {
1821
+ console.warn(
1822
+ `Could not stringify public env process.env.${key} env variable`
1823
+ );
1824
+ console.warn(error);
1825
+ }
1826
+ }
1827
+ });
1828
+ const staticMediaPath = import_node_path2.default.join(
1829
+ configManager.generatedFolderPath,
1830
+ "static-media.json"
1831
+ );
1832
+ if ((_b = (_a = configManager.config.media) == null ? void 0 : _a.tina) == null ? void 0 : _b.static) {
1833
+ const staticMedia = await listFilesRecursively({
1834
+ directoryPath: ((_c = configManager.config.media.tina) == null ? void 0 : _c.mediaRoot) || "",
1835
+ config: configManager.config.media.tina,
1836
+ roothPath: configManager.rootPath
2167
1837
  });
1838
+ await import_fs_extra4.default.outputFile(staticMediaPath, JSON.stringify(staticMedia, null, 2));
1839
+ } else {
1840
+ await import_fs_extra4.default.outputFile(staticMediaPath, `[]`);
2168
1841
  }
2169
- }
1842
+ const alias = {
1843
+ TINA_IMPORT: configManager.prebuildFilePath,
1844
+ SCHEMA_IMPORT: configManager.generatedGraphQLJSONPath,
1845
+ STATIC_MEDIA_IMPORT: staticMediaPath,
1846
+ crypto: import_node_path2.default.join(configManager.spaRootPath, "src", "dummy-client.ts"),
1847
+ fs: import_node_path2.default.join(configManager.spaRootPath, "src", "dummy-client.ts"),
1848
+ os: import_node_path2.default.join(configManager.spaRootPath, "src", "dummy-client.ts"),
1849
+ path: import_node_path2.default.join(configManager.spaRootPath, "src", "dummy-client.ts")
1850
+ };
1851
+ if (configManager.shouldSkipSDK()) {
1852
+ alias["CLIENT_IMPORT"] = import_node_path2.default.join(
1853
+ configManager.spaRootPath,
1854
+ "src",
1855
+ "dummy-client.ts"
1856
+ );
1857
+ } else {
1858
+ alias["CLIENT_IMPORT"] = configManager.isUsingTs() ? configManager.generatedTypesTSFilePath : configManager.generatedTypesJSFilePath;
1859
+ }
1860
+ let basePath;
1861
+ if (configManager.config.build.basePath) {
1862
+ basePath = configManager.config.build.basePath;
1863
+ }
1864
+ const fullVersion = configManager.getTinaGraphQLVersion();
1865
+ const version2 = `${fullVersion.major}.${fullVersion.minor}`;
1866
+ const config2 = {
1867
+ root: configManager.spaRootPath,
1868
+ base: `/${basePath ? `${(0, import_normalize_path3.default)(basePath)}/` : ""}${(0, import_normalize_path3.default)(
1869
+ configManager.config.build.outputFolder
1870
+ )}/`,
1871
+ appType: "spa",
1872
+ resolve: {
1873
+ alias,
1874
+ dedupe: ["graphql", "tinacms", "react", "react-dom", "react-router-dom"]
1875
+ },
1876
+ define: {
1877
+ /**
1878
+ * Since we prebuild the config.ts, it's possible for modules to be loaded which make
1879
+ * use of `process`. The main scenario where this is an issue is when co-locating schema
1880
+ * definitions with source files, and specifically source files which impor from NextJS.
1881
+ *
1882
+ * Some examples of what NextJS uses for `process.env` are:
1883
+ * - `process.env.__NEXT_TRAILING_SLASH`
1884
+ * - `process.env.__NEXT_CROSS_ORIGIN`
1885
+ * - `process.env.__NEXT_I18N_SUPPORT`
1886
+ *
1887
+ * Also, interestingly some of the advice for handling this doesn't work, references to replacing
1888
+ * `process.env` with `{}` are problematic, because browsers don't understand the `{}.` syntax,
1889
+ * but node does. This was a surprise, but using `new Object()` seems to do the trick.
1890
+ */
1891
+ "process.env": `new Object(${JSON.stringify(publicEnv)})`,
1892
+ // Used by picomatch https://github.com/micromatch/picomatch/blob/master/lib/utils.js#L4
1893
+ "process.platform": `"${process.platform}"`,
1894
+ __API_URL__: `"${apiURL}"`,
1895
+ __BASE_PATH__: `"${((_e = (_d = configManager.config) == null ? void 0 : _d.build) == null ? void 0 : _e.basePath) || ""}"`,
1896
+ __TINA_GRAPHQL_VERSION__: version2
1897
+ },
1898
+ logLevel: "error",
1899
+ // Vite import warnings are noisy
1900
+ optimizeDeps: {
1901
+ force: true,
1902
+ // Not 100% sure why this isn't being picked up automatically, this works from within the monorepo
1903
+ // but breaks externally
1904
+ include: ["react/jsx-runtime", "react/jsx-dev-runtime"]
1905
+ },
1906
+ server: {
1907
+ host: (_h = (_g = (_f = configManager.config) == null ? void 0 : _f.build) == null ? void 0 : _g.host) != null ? _h : false,
1908
+ watch: noWatch ? {
1909
+ ignored: ["**/*"]
1910
+ } : {
1911
+ // Ignore everything except for the alias fields we specified above
1912
+ ignored: [
1913
+ `${configManager.tinaFolderPath}/**/!(config.prebuild.jsx|_graphql.json)`
1914
+ ]
1915
+ },
1916
+ fs: {
1917
+ strict: false
1918
+ }
1919
+ },
1920
+ build: {
1921
+ sourcemap: false,
1922
+ outDir: configManager.outputFolderPath,
1923
+ emptyOutDir: true,
1924
+ rollupOptions
1925
+ },
1926
+ plugins: [
1927
+ /**
1928
+ * `splitVendorChunkPlugin` is needed because `tinacms` is quite large,
1929
+ * Vite's chunking strategy chokes on memory issues for smaller machines (ie. on CI).
1930
+ */
1931
+ (0, import_plugin_react.default)({
1932
+ babel: {
1933
+ // Supresses the warning [NOTE] babel The code generator has deoptimised the styling of
1934
+ compact: true
1935
+ }
1936
+ }),
1937
+ (0, import_vite.splitVendorChunkPlugin)(),
1938
+ tinaTailwind(configManager.spaRootPath, configManager.prebuildFilePath),
1939
+ ...plugins
1940
+ ]
1941
+ };
1942
+ return config2;
1943
+ };
2170
1944
 
2171
- // src/next/commands/baseCommands.ts
1945
+ // src/next/vite/plugins.ts
1946
+ var import_pluginutils = require("@rollup/pluginutils");
1947
+ var import_fs = __toESM(require("fs"));
1948
+ var import_vite2 = require("vite");
1949
+ var import_esbuild2 = require("esbuild");
1950
+ var import_path4 = __toESM(require("path"));
1951
+ var import_body_parser = __toESM(require("body-parser"));
1952
+ var import_cors = __toESM(require("cors"));
2172
1953
  var import_graphql9 = require("@tinacms/graphql");
1954
+
1955
+ // src/next/commands/dev-command/server/media.ts
2173
1956
  var import_fs_extra5 = __toESM(require("fs-extra"));
2174
- var BaseCommand = class extends import_clipanion.Command {
2175
- constructor() {
2176
- super(...arguments);
2177
- this.experimentalDataLayer = import_clipanion.Option.Boolean("--experimentalData", {
2178
- description: "DEPRECATED - Build the server with additional data querying capabilities"
2179
- });
2180
- this.isomorphicGitBridge = import_clipanion.Option.Boolean("--isomorphicGitBridge", {
2181
- description: "DEPRECATED - Enable Isomorphic Git Bridge Implementation"
2182
- });
2183
- this.port = import_clipanion.Option.String("-p,--port", "4001", {
2184
- description: "Specify a port to run the server on. (default 4001)"
2185
- });
2186
- this.datalayerPort = import_clipanion.Option.String("--datalayer-port", "9000", {
2187
- description: "Specify a port to run the datalayer server on. (default 9000)"
2188
- });
2189
- this.subCommand = import_clipanion.Option.String("-c,--command", {
2190
- description: "The sub-command to run"
2191
- });
2192
- this.rootPath = import_clipanion.Option.String("--rootPath", {
2193
- description: "Specify the root directory to run the CLI from (defaults to current working directory)"
1957
+ var import_path3 = __toESM(require("path"));
1958
+ var import_busboy = __toESM(require("busboy"));
1959
+ var createMediaRouter = (config2) => {
1960
+ const mediaFolder = import_path3.default.join(
1961
+ config2.rootPath,
1962
+ config2.publicFolder,
1963
+ config2.mediaRoot
1964
+ );
1965
+ const mediaModel = new MediaModel(config2);
1966
+ const handleList = async (req, res) => {
1967
+ const requestURL = new URL(req.url, config2.apiURL);
1968
+ const folder = requestURL.pathname.replace("/media/list/", "");
1969
+ const limit = requestURL.searchParams.get("limit");
1970
+ const cursor = requestURL.searchParams.get("cursor");
1971
+ const media = await mediaModel.listMedia({
1972
+ searchPath: folder,
1973
+ cursor,
1974
+ limit
2194
1975
  });
2195
- this.verbose = import_clipanion.Option.Boolean("-v,--verbose", false, {
2196
- description: "increase verbosity of logged output"
1976
+ res.end(JSON.stringify(media));
1977
+ };
1978
+ const handleDelete = async (req, res) => {
1979
+ const file = decodeURIComponent(req.url.slice("/media/".length));
1980
+ const didDelete = await mediaModel.deleteMedia({ searchPath: file });
1981
+ res.end(JSON.stringify(didDelete));
1982
+ };
1983
+ const handlePost = async function(req, res) {
1984
+ const bb = (0, import_busboy.default)({ headers: req.headers });
1985
+ bb.on("file", async (_name, file, _info) => {
1986
+ var _a;
1987
+ const fullPath = decodeURI((_a = req.url) == null ? void 0 : _a.slice("/media/upload/".length));
1988
+ const saveTo = import_path3.default.join(mediaFolder, ...fullPath.split("/"));
1989
+ await import_fs_extra5.default.ensureDir(import_path3.default.dirname(saveTo));
1990
+ file.pipe(import_fs_extra5.default.createWriteStream(saveTo));
2197
1991
  });
2198
- this.noSDK = import_clipanion.Option.Boolean("--noSDK", false, {
2199
- description: "DEPRECATED - This should now be set in the config at client.skip = true'. Don't generate the generated client SDK"
1992
+ bb.on("error", (error) => {
1993
+ res.statusCode = 500;
1994
+ if (error instanceof Error) {
1995
+ res.end(JSON.stringify({ message: error }));
1996
+ } else {
1997
+ res.end(JSON.stringify({ message: "Unknown error while uploading" }));
1998
+ }
2200
1999
  });
2201
- this.noTelemetry = import_clipanion.Option.Boolean("--noTelemetry", false, {
2202
- description: "Disable anonymous telemetry that is collected"
2000
+ bb.on("close", () => {
2001
+ res.statusCode = 200;
2002
+ res.end(JSON.stringify({ success: true }));
2203
2003
  });
2004
+ req.pipe(bb);
2005
+ };
2006
+ return { handleList, handleDelete, handlePost };
2007
+ };
2008
+ var parseMediaFolder = (str) => {
2009
+ let returnString = str;
2010
+ if (returnString.startsWith("/")) returnString = returnString.substr(1);
2011
+ if (returnString.endsWith("/"))
2012
+ returnString = returnString.substr(0, returnString.length - 1);
2013
+ return returnString;
2014
+ };
2015
+ var MediaModel = class {
2016
+ constructor({ rootPath, publicFolder, mediaRoot }) {
2017
+ this.rootPath = rootPath;
2018
+ this.mediaRoot = mediaRoot;
2019
+ this.publicFolder = publicFolder;
2204
2020
  }
2205
- async startSubCommand() {
2206
- let subProc;
2207
- if (this.subCommand) {
2208
- subProc = await startSubprocess2({ command: this.subCommand });
2209
- logger.info(
2210
- `Running web application with command: ${import_chalk4.default.cyan(this.subCommand)}`
2021
+ async listMedia(args) {
2022
+ try {
2023
+ const folderPath = (0, import_path3.join)(
2024
+ this.rootPath,
2025
+ this.publicFolder,
2026
+ this.mediaRoot,
2027
+ decodeURIComponent(args.searchPath)
2211
2028
  );
2212
- }
2213
- function exitHandler(options, exitCode) {
2214
- if (subProc) {
2215
- subProc.kill();
2029
+ const searchPath = parseMediaFolder(args.searchPath);
2030
+ if (!await import_fs_extra5.default.pathExists(folderPath)) {
2031
+ return {
2032
+ files: [],
2033
+ directories: []
2034
+ };
2216
2035
  }
2217
- process.exit();
2036
+ const filesStr = await import_fs_extra5.default.readdir(folderPath);
2037
+ const filesProm = filesStr.map(async (file) => {
2038
+ const filePath = (0, import_path3.join)(folderPath, file);
2039
+ const stat = await import_fs_extra5.default.stat(filePath);
2040
+ let src = `/${file}`;
2041
+ const isFile = stat.isFile();
2042
+ if (!isFile) {
2043
+ return {
2044
+ isFile,
2045
+ size: stat.size,
2046
+ src,
2047
+ filename: file
2048
+ };
2049
+ }
2050
+ if (searchPath) {
2051
+ src = `/${searchPath}${src}`;
2052
+ }
2053
+ if (this.mediaRoot) {
2054
+ src = `/${this.mediaRoot}${src}`;
2055
+ }
2056
+ return {
2057
+ isFile,
2058
+ size: stat.size,
2059
+ src,
2060
+ filename: file
2061
+ };
2062
+ });
2063
+ const offset = Number(args.cursor) || 0;
2064
+ const limit = Number(args.limit) || 20;
2065
+ const rawItems = await Promise.all(filesProm);
2066
+ const sortedItems = rawItems.sort((a, b) => {
2067
+ if (a.isFile && !b.isFile) {
2068
+ return 1;
2069
+ }
2070
+ if (!a.isFile && b.isFile) {
2071
+ return -1;
2072
+ }
2073
+ return 0;
2074
+ });
2075
+ const limitItems = sortedItems.slice(offset, offset + limit);
2076
+ const files = limitItems.filter((x) => x.isFile);
2077
+ const directories = limitItems.filter((x) => !x.isFile).map((x) => x.src);
2078
+ const cursor = rawItems.length > offset + limit ? String(offset + limit) : null;
2079
+ return {
2080
+ files,
2081
+ directories,
2082
+ cursor
2083
+ };
2084
+ } catch (error) {
2085
+ console.error(error);
2086
+ return {
2087
+ files: [],
2088
+ directories: [],
2089
+ error: error == null ? void 0 : error.toString()
2090
+ };
2218
2091
  }
2219
- process.on("exit", exitHandler);
2220
- process.on("SIGINT", exitHandler);
2221
- process.on("SIGUSR1", exitHandler);
2222
- process.on("SIGUSR2", exitHandler);
2223
- process.on("uncaughtException", (error) => {
2224
- logger.error(`Uncaught exception ${error.name}`);
2092
+ }
2093
+ async deleteMedia(args) {
2094
+ try {
2095
+ const file = (0, import_path3.join)(
2096
+ this.rootPath,
2097
+ this.publicFolder,
2098
+ this.mediaRoot,
2099
+ decodeURIComponent(args.searchPath)
2100
+ );
2101
+ await import_fs_extra5.default.stat(file);
2102
+ await import_fs_extra5.default.remove(file);
2103
+ return { ok: true };
2104
+ } catch (error) {
2225
2105
  console.error(error);
2226
- });
2106
+ return { ok: false, message: error == null ? void 0 : error.toString() };
2107
+ }
2227
2108
  }
2228
- logDeprecationWarnings() {
2229
- if (this.isomorphicGitBridge) {
2230
- logger.warn("--isomorphicGitBridge has been deprecated");
2109
+ };
2110
+
2111
+ // src/next/commands/dev-command/server/searchIndex.ts
2112
+ var createSearchIndexRouter = ({
2113
+ config: config2,
2114
+ searchIndex
2115
+ }) => {
2116
+ const put = async (req, res) => {
2117
+ const { docs } = req.body;
2118
+ const result = await searchIndex.PUT(docs);
2119
+ res.writeHead(200, { "Content-Type": "application/json" });
2120
+ res.end(JSON.stringify({ result }));
2121
+ };
2122
+ const get = async (req, res) => {
2123
+ const requestURL = new URL(req.url, config2.apiURL);
2124
+ const query = requestURL.searchParams.get("q");
2125
+ const optionsParam = requestURL.searchParams.get("options");
2126
+ let options = {
2127
+ DOCUMENTS: false
2128
+ };
2129
+ if (optionsParam) {
2130
+ options = {
2131
+ ...options,
2132
+ ...JSON.parse(optionsParam)
2133
+ };
2231
2134
  }
2232
- if (this.experimentalDataLayer) {
2233
- logger.warn(
2234
- "--experimentalDataLayer has been deprecated, the data layer is now built-in automatically"
2235
- );
2135
+ res.writeHead(200, { "Content-Type": "application/json" });
2136
+ if (query) {
2137
+ const result = await searchIndex.QUERY(JSON.parse(query), options);
2138
+ res.end(JSON.stringify(result));
2139
+ } else {
2140
+ res.end(JSON.stringify({ RESULT: [] }));
2236
2141
  }
2237
- if (this.noSDK) {
2238
- logger.warn(
2239
- "--noSDK has been deprecated, and will be unsupported in a future release. This should be set in the config at client.skip = true"
2240
- );
2142
+ };
2143
+ const del = async (req, res) => {
2144
+ const requestURL = new URL(req.url, config2.apiURL);
2145
+ const docId = requestURL.pathname.split("/").filter(Boolean).slice(1).join("/");
2146
+ const result = await searchIndex.DELETE(docId);
2147
+ res.writeHead(200, { "Content-Type": "application/json" });
2148
+ res.end(JSON.stringify({ result }));
2149
+ };
2150
+ return { del, get, put };
2151
+ };
2152
+
2153
+ // src/next/vite/plugins.ts
2154
+ var transformTsxPlugin = ({
2155
+ configManager: _configManager
2156
+ }) => {
2157
+ const plug = {
2158
+ name: "transform-tsx",
2159
+ async transform(code, id) {
2160
+ const extName = import_path4.default.extname(id);
2161
+ if (extName.startsWith(".tsx") || extName.startsWith(".ts")) {
2162
+ const result = await (0, import_esbuild2.transform)(code, { loader: "tsx" });
2163
+ return {
2164
+ code: result.code
2165
+ };
2166
+ }
2241
2167
  }
2242
- }
2243
- async indexContentWithSpinner({
2244
- database,
2245
- graphQLSchema,
2246
- tinaSchema,
2247
- configManager,
2248
- partialReindex,
2249
- text
2250
- }) {
2251
- const textToUse = text || "Indexing local files";
2252
- const warnings = [];
2253
- await spin({
2254
- waitFor: async () => {
2255
- var _a, _b;
2256
- const rootPath = configManager.rootPath;
2257
- let sha;
2258
- try {
2259
- sha = await (0, import_graphql9.getSha)({ fs: import_fs_extra5.default, dir: rootPath });
2260
- } catch (e) {
2261
- if (partialReindex) {
2262
- console.error(
2263
- "Failed to get sha. NOTE: `--partial-reindex` only supported for git repositories"
2264
- );
2265
- throw e;
2266
- }
2168
+ };
2169
+ return plug;
2170
+ };
2171
+ var devServerEndPointsPlugin = ({
2172
+ configManager,
2173
+ apiURL,
2174
+ database,
2175
+ searchIndex,
2176
+ databaseLock
2177
+ }) => {
2178
+ const plug = {
2179
+ name: "graphql-endpoints",
2180
+ configureServer(server) {
2181
+ server.middlewares.use((0, import_cors.default)());
2182
+ server.middlewares.use(import_body_parser.default.json({ limit: "5mb" }));
2183
+ server.middlewares.use(async (req, res, next) => {
2184
+ var _a;
2185
+ const mediaPaths = (_a = configManager.config.media) == null ? void 0 : _a.tina;
2186
+ const mediaRouter = createMediaRouter({
2187
+ rootPath: configManager.rootPath,
2188
+ apiURL,
2189
+ publicFolder: parseMediaFolder((mediaPaths == null ? void 0 : mediaPaths.publicFolder) || ""),
2190
+ mediaRoot: parseMediaFolder((mediaPaths == null ? void 0 : mediaPaths.mediaRoot) || "")
2191
+ });
2192
+ const searchIndexRouter = createSearchIndexRouter({
2193
+ config: { apiURL, searchPath: "searchIndex" },
2194
+ searchIndex
2195
+ });
2196
+ if (req.url.startsWith("/media/upload")) {
2197
+ await mediaRouter.handlePost(req, res);
2198
+ return;
2267
2199
  }
2268
- const lastSha = await database.getMetadata("lastSha");
2269
- const exists = lastSha && await (0, import_graphql9.shaExists)({ fs: import_fs_extra5.default, dir: rootPath, sha: lastSha });
2270
- let res;
2271
- if (partialReindex && lastSha && exists && sha) {
2272
- const pathFilter = {};
2273
- if (configManager.isUsingLegacyFolder) {
2274
- pathFilter[".tina/__generated__/_schema.json"] = {};
2275
- } else {
2276
- pathFilter["tina/tina-lock.json"] = {};
2277
- }
2278
- for (const collection of tinaSchema.getCollections()) {
2279
- pathFilter[collection.path] = {
2280
- matches: ((_a = collection.match) == null ? void 0 : _a.exclude) || ((_b = collection.match) == null ? void 0 : _b.include) ? tinaSchema.getMatches({ collection }) : void 0
2281
- };
2200
+ if (req.url.startsWith("/media")) {
2201
+ if (req.method === "DELETE") {
2202
+ await mediaRouter.handleDelete(req, res);
2203
+ return;
2282
2204
  }
2283
- const { added, modified, deleted } = await (0, import_graphql9.getChangedFiles)({
2284
- fs: import_fs_extra5.default,
2285
- dir: rootPath,
2286
- from: lastSha,
2287
- to: sha,
2288
- pathFilter
2289
- });
2290
- const tinaPathUpdates = modified.filter(
2291
- (path14) => path14.startsWith(".tina/__generated__/_schema.json") || path14.startsWith("tina/tina-lock.json")
2205
+ }
2206
+ if (req.url.startsWith("/media/list")) {
2207
+ await mediaRouter.handleList(req, res);
2208
+ return;
2209
+ }
2210
+ if (req.url === "/altair") {
2211
+ res.end(
2212
+ JSON.stringify({
2213
+ status: "The GraphQL playground has moved to <your-dev-url>/index.html#/graphql"
2214
+ })
2292
2215
  );
2293
- if (tinaPathUpdates.length > 0) {
2294
- res = await database.indexContent({
2295
- graphQLSchema,
2296
- tinaSchema
2216
+ return;
2217
+ }
2218
+ if (req.url === "/graphql") {
2219
+ const { query, variables } = req.body;
2220
+ let result;
2221
+ await databaseLock(async () => {
2222
+ result = await (0, import_graphql9.resolve)({
2223
+ config: {
2224
+ useRelativeMedia: true
2225
+ },
2226
+ database,
2227
+ query,
2228
+ variables,
2229
+ verbose: false
2297
2230
  });
2298
- } else {
2299
- if (added.length > 0 || modified.length > 0) {
2300
- await database.indexContentByPaths([...added, ...modified]);
2301
- }
2302
- if (deleted.length > 0) {
2303
- await database.deleteContentByPaths(deleted);
2304
- }
2305
- }
2306
- } else {
2307
- res = await database.indexContent({
2308
- graphQLSchema,
2309
- tinaSchema
2310
2231
  });
2232
+ res.end(JSON.stringify(result));
2233
+ return;
2311
2234
  }
2312
- if (sha) {
2313
- await database.setMetadata("lastSha", sha);
2314
- }
2315
- if (res == null ? void 0 : res.warnings) {
2316
- warnings.push(...res.warnings);
2235
+ if (req.url.startsWith("/searchIndex")) {
2236
+ if (req.method === "POST") {
2237
+ await searchIndexRouter.put(req, res);
2238
+ } else if (req.method === "GET") {
2239
+ await searchIndexRouter.get(req, res);
2240
+ } else if (req.method === "DELETE") {
2241
+ await searchIndexRouter.del(req, res);
2242
+ }
2243
+ return;
2317
2244
  }
2318
- },
2319
- text: textToUse
2320
- });
2321
- if (warnings.length > 0) {
2322
- logger.warn(`Indexing completed with ${warnings.length} warning(s)`);
2323
- warnings.forEach((warning) => {
2324
- logger.warn(warnText(`${warning}`));
2245
+ next();
2325
2246
  });
2326
2247
  }
2327
- }
2248
+ };
2249
+ return plug;
2250
+ };
2251
+ function viteTransformExtension({
2252
+ exportAsDefault = true,
2253
+ svgrOptions,
2254
+ esbuildOptions,
2255
+ include = "**/*.svg",
2256
+ exclude
2257
+ } = {}) {
2258
+ const filter = (0, import_pluginutils.createFilter)(include, exclude);
2259
+ return {
2260
+ name: "vite-plugin-svgr",
2261
+ async transform(code, id) {
2262
+ if (filter(id)) {
2263
+ const { transform: transform2 } = await Promise.resolve().then(() => __toESM(require("@svgr/core")));
2264
+ const svgCode = await import_fs.default.promises.readFile(
2265
+ id.replace(/\?.*$/, ""),
2266
+ "utf8"
2267
+ );
2268
+ const componentCode = await transform2(svgCode, svgrOptions, {
2269
+ filePath: id,
2270
+ caller: {
2271
+ previousExport: exportAsDefault ? null : code
2272
+ }
2273
+ });
2274
+ const res = await (0, import_vite2.transformWithEsbuild)(componentCode, id, {
2275
+ loader: "jsx",
2276
+ ...esbuildOptions
2277
+ });
2278
+ return {
2279
+ code: res.code,
2280
+ map: null
2281
+ // TODO:
2282
+ };
2283
+ }
2284
+ }
2285
+ };
2286
+ }
2287
+
2288
+ // src/next/commands/dev-command/server/index.ts
2289
+ var createDevServer = async (configManager, database, searchIndex, apiURL, noWatch, databaseLock) => {
2290
+ const plugins = [
2291
+ transformTsxPlugin({ configManager }),
2292
+ devServerEndPointsPlugin({
2293
+ apiURL,
2294
+ configManager,
2295
+ database,
2296
+ searchIndex,
2297
+ databaseLock
2298
+ }),
2299
+ viteTransformExtension()
2300
+ ];
2301
+ return (0, import_vite3.createServer)(
2302
+ await createConfig({
2303
+ configManager,
2304
+ database,
2305
+ apiURL,
2306
+ plugins,
2307
+ noWatch,
2308
+ /**
2309
+ * Ensure Vite's import scan uses the spaMainPath as the input
2310
+ * so it properly finds everything. This is for dev only, and when
2311
+ * running the server outside of this monorepo vite fails to find
2312
+ * and optimize the imports, so you get errors about it not being
2313
+ * able to find an export from a module, and it's always a CJS
2314
+ * module that Vite would usually transform to an ES module.
2315
+ */
2316
+ rollupOptions: {
2317
+ input: configManager.spaMainPath,
2318
+ onwarn(warning, warn) {
2319
+ if (warning.code === "MODULE_LEVEL_DIRECTIVE") {
2320
+ return;
2321
+ }
2322
+ warn(warning);
2323
+ }
2324
+ }
2325
+ })
2326
+ );
2328
2327
  };
2329
2328
 
2330
2329
  // src/next/commands/dev-command/index.ts
2331
- var import_search = require("@tinacms/search");
2332
2330
  var DevCommand = class extends BaseCommand {
2333
2331
  constructor() {
2334
2332
  super(...arguments);
@@ -2652,12 +2650,41 @@ DevCommand.usage = import_clipanion2.Command.Usage({
2652
2650
  });
2653
2651
 
2654
2652
  // src/next/commands/build-command/index.ts
2655
- var import_clipanion3 = require("clipanion");
2656
- var import_progress2 = __toESM(require("progress"));
2657
- var import_fs_extra7 = __toESM(require("fs-extra"));
2658
2653
  var import_crypto = __toESM(require("crypto"));
2659
2654
  var import_path6 = __toESM(require("path"));
2655
+ var import_core3 = require("@graphql-inspector/core");
2660
2656
  var import_graphql11 = require("@tinacms/graphql");
2657
+ var import_schema_tools2 = require("@tinacms/schema-tools");
2658
+ var import_search2 = require("@tinacms/search");
2659
+ var import_clipanion3 = require("clipanion");
2660
+ var import_fs_extra7 = __toESM(require("fs-extra"));
2661
+ var import_graphql12 = require("graphql");
2662
+ var import_progress2 = __toESM(require("progress"));
2663
+
2664
+ // src/utils/index.ts
2665
+ var import_core2 = require("@graphql-inspector/core");
2666
+ var getFaqLink = (type) => {
2667
+ switch (type) {
2668
+ case import_core2.ChangeType.FieldRemoved: {
2669
+ return "https://tina.io/docs/introduction/faq#how-do-i-resolve-the-local-graphql-schema-doesnt-match-the-remote-graphql-schema-errors";
2670
+ }
2671
+ default:
2672
+ return null;
2673
+ }
2674
+ };
2675
+
2676
+ // src/utils/sleep.ts
2677
+ function timeout(ms) {
2678
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
2679
+ }
2680
+ async function sleepAndCallFunc({
2681
+ fn,
2682
+ ms
2683
+ }) {
2684
+ await timeout(ms);
2685
+ const res = await fn();
2686
+ return res;
2687
+ }
2661
2688
 
2662
2689
  // src/next/commands/build-command/server.ts
2663
2690
  var import_vite5 = require("vite");
@@ -2697,29 +2724,9 @@ var buildProductionSpa = async (configManager, database, apiURL) => {
2697
2724
  return (0, import_vite5.build)(config2);
2698
2725
  };
2699
2726
 
2700
- // src/next/commands/build-command/index.ts
2701
- var import_schema_tools2 = require("@tinacms/schema-tools");
2702
- var import_graphql12 = require("graphql");
2703
- var import_core3 = require("@graphql-inspector/core");
2704
-
2705
2727
  // src/next/commands/build-command/waitForDB.ts
2706
- var import_progress = __toESM(require("progress"));
2707
2728
  var import_schema_tools = require("@tinacms/schema-tools");
2708
-
2709
- // src/utils/sleep.ts
2710
- function timeout(ms) {
2711
- return new Promise((resolve2) => setTimeout(resolve2, ms));
2712
- }
2713
- async function sleepAndCallFunc({
2714
- fn,
2715
- ms
2716
- }) {
2717
- await timeout(ms);
2718
- const res = await fn();
2719
- return res;
2720
- }
2721
-
2722
- // src/next/commands/build-command/waitForDB.ts
2729
+ var import_progress = __toESM(require("progress"));
2723
2730
  var POLLING_INTERVAL = 5e3;
2724
2731
  var STATUS_INPROGRESS = "inprogress";
2725
2732
  var STATUS_COMPLETE = "complete";
@@ -2735,12 +2742,12 @@ var waitForDB = async (config2, apiUrl, previewName, verbose) => {
2735
2742
  const { clientId, branch, isLocalClient, host } = (0, import_schema_tools.parseURL)(apiUrl);
2736
2743
  if (isLocalClient || !host || !clientId || !branch) {
2737
2744
  if (verbose) {
2738
- logger.info(logText("Not using Tina Cloud, skipping DB check"));
2745
+ logger.info(logText("Not using TinaCloud, skipping DB check"));
2739
2746
  }
2740
2747
  return;
2741
2748
  }
2742
2749
  const bar2 = new import_progress.default(
2743
- "Checking indexing process in Tina Cloud... :prog",
2750
+ "Checking indexing process in TinaCloud... :prog",
2744
2751
  1
2745
2752
  );
2746
2753
  const pollForStatus = async () => {
@@ -2774,11 +2781,11 @@ var waitForDB = async (config2, apiUrl, previewName, verbose) => {
2774
2781
  await sleepAndCallFunc({ fn: pollForStatus, ms: POLLING_INTERVAL });
2775
2782
  } else if (status === STATUS_FAILED) {
2776
2783
  throw new IndexFailedError(
2777
- `Attempting to index but responded with status 'failed'. To retry the indexing process, click the "Reindex" button for '${previewName || branch}' in the Tina Cloud configuration for this project. ${error}`
2784
+ `Attempting to index but responded with status 'failed'. To retry the indexing process, click the "Reindex" button for '${previewName || branch}' in the TinaCloud configuration for this project. ${error}`
2778
2785
  );
2779
2786
  } else {
2780
2787
  throw new IndexFailedError(
2781
- `Attempting to index but responded with status 'unknown'. To retry the indexing process, click the "Reindex" button for '${previewName || branch}' in the Tina Cloud configuration for this project. ${error}`
2788
+ `Attempting to index but responded with status 'unknown'. To retry the indexing process, click the "Reindex" button for '${previewName || branch}' in the TinaCloud configuration for this project. ${error}`
2782
2789
  );
2783
2790
  }
2784
2791
  } catch (e) {
@@ -2795,26 +2802,11 @@ var waitForDB = async (config2, apiUrl, previewName, verbose) => {
2795
2802
  }
2796
2803
  };
2797
2804
  await spin({
2798
- text: "Checking indexing process in Tina Cloud...",
2805
+ text: "Checking indexing process in TinaCloud...",
2799
2806
  waitFor: pollForStatus
2800
2807
  });
2801
2808
  };
2802
2809
 
2803
- // src/next/commands/build-command/index.ts
2804
- var import_search2 = require("@tinacms/search");
2805
-
2806
- // src/utils/index.ts
2807
- var import_core2 = require("@graphql-inspector/core");
2808
- var getFaqLink = (type) => {
2809
- switch (type) {
2810
- case import_core2.ChangeType.FieldRemoved: {
2811
- return "https://tina.io/docs/introduction/faq#how-do-i-resolve-the-local-graphql-schema-doesnt-match-the-remote-graphql-schema-errors";
2812
- }
2813
- default:
2814
- return null;
2815
- }
2816
- };
2817
-
2818
2810
  // src/next/commands/build-command/index.ts
2819
2811
  var BuildCommand = class extends BaseCommand {
2820
2812
  constructor() {
@@ -2832,7 +2824,7 @@ var BuildCommand = class extends BaseCommand {
2832
2824
  description: "Specify the version of @tinacms/graphql to use (defaults to latest)"
2833
2825
  });
2834
2826
  /**
2835
- * This option allows the user to skip the tina cloud checks if they want to. This could be useful for mismatched GraphQL versions or if they want to build only using the local client and never connect to Tina Cloud
2827
+ * This option allows the user to skip the TinaCloud checks if they want to. This could be useful for mismatched GraphQL versions or if they want to build only using the local client and never connect to TinaCloud
2836
2828
  */
2837
2829
  this.skipCloudChecks = import_clipanion3.Option.Boolean("--skip-cloud-checks", false, {
2838
2830
  description: "Skips checking the provided cloud config."
@@ -3147,10 +3139,7 @@ ${dangerText(e.message)}
3147
3139
  });
3148
3140
  throw e;
3149
3141
  }
3150
- const branchBar = new import_progress2.default(
3151
- "Checking branch is on Tina Cloud. :prog",
3152
- 1
3153
- );
3142
+ const branchBar = new import_progress2.default("Checking branch is on TinaCloud. :prog", 1);
3154
3143
  if (branchKnown) {
3155
3144
  branchBar.tick({
3156
3145
  prog: "\u2705"
@@ -3187,12 +3176,12 @@ ${dangerText(e.message)}
3187
3176
  });
3188
3177
  logger.error(
3189
3178
  `${dangerText(
3190
- `ERROR: Branch '${branch}' is not on Tina Cloud.`
3179
+ `ERROR: Branch '${branch}' is not on TinaCloud.`
3191
3180
  )} Please make sure that branch '${branch}' exists in your repository and that you have pushed your all changes to the remote. View all all branches and there current status here: ${linkText(
3192
3181
  `https://app.tina.io/projects/${clientId}/configuration`
3193
3182
  )}`
3194
3183
  );
3195
- throw new Error("Branch is not on Tina Cloud");
3184
+ throw new Error("Branch is not on TinaCloud");
3196
3185
  }
3197
3186
  async syncProject(configManager, apiURL, options) {
3198
3187
  const { config: config2 } = configManager;
@@ -3331,9 +3320,7 @@ Additional info:
3331
3320
  const { clientId, branch, isLocalClient, host } = (0, import_schema_tools2.parseURL)(apiURL);
3332
3321
  if (isLocalClient || !host || !clientId || !branch) {
3333
3322
  if (verbose) {
3334
- logger.info(
3335
- logText("Not using Tina Cloud, skipping Tina Schema check")
3336
- );
3323
+ logger.info(logText("Not using TinaCloud, skipping Tina Schema check"));
3337
3324
  }
3338
3325
  return;
3339
3326
  }
@@ -3392,7 +3379,7 @@ Additional info:
3392
3379
  BuildCommand.paths = [["build"]];
3393
3380
  BuildCommand.usage = import_clipanion3.Command.Usage({
3394
3381
  category: `Commands`,
3395
- description: `Build the CMS and autogenerated modules for usage with Tina Cloud`
3382
+ description: `Build the CMS and autogenerated modules for usage with TinaCloud`
3396
3383
  });
3397
3384
  async function request(args) {
3398
3385
  const headers = new Headers();
@@ -3894,7 +3881,7 @@ var tinaCloudSetupQuestions = [
3894
3881
  {
3895
3882
  name: "clientId",
3896
3883
  type: "text",
3897
- message: `What is your Tina Cloud Client ID? (Hit enter to skip and set up yourself later)
3884
+ message: `What is your TinaCloud Client ID? (Hit enter to skip and set up yourself later)
3898
3885
  ${logText(
3899
3886
  "Don't have a Client ID? Create one here: "
3900
3887
  )}${linkText("https://app.tina.io/projects/new")}`,
@@ -3903,7 +3890,7 @@ ${logText(
3903
3890
  {
3904
3891
  name: "token",
3905
3892
  type: "text",
3906
- message: (prev) => `What is your Tina Cloud Read Only Token?
3893
+ message: (prev) => `What is your TinaCloud Read Only Token?
3907
3894
  ${logText(
3908
3895
  "Don't have a Read Only Token? Create one here: "
3909
3896
  )}${linkText(`https://app.tina.io/projects/${prev || "[XXX]"}/tokens`)}`,
@@ -4114,8 +4101,8 @@ var chooseDatabaseAdapter = async ({
4114
4101
  };
4115
4102
 
4116
4103
  // src/cmds/init/prompts/authProvider.ts
4117
- var import_prompts5 = __toESM(require("prompts"));
4118
4104
  var import_crypto_js = __toESM(require("crypto-js"));
4105
+ var import_prompts5 = __toESM(require("prompts"));
4119
4106
  var supportedAuthProviders = {
4120
4107
  other: {
4121
4108
  name: "other"
@@ -4292,7 +4279,7 @@ var askIfUsingSelfHosted = async () => {
4292
4279
  type: "select",
4293
4280
  choices: [
4294
4281
  {
4295
- title: "Tina Cloud",
4282
+ title: "TinaCloud",
4296
4283
  value: "tina-cloud"
4297
4284
  },
4298
4285
  {
@@ -4300,7 +4287,7 @@ var askIfUsingSelfHosted = async () => {
4300
4287
  value: "self-host"
4301
4288
  }
4302
4289
  ],
4303
- message: "Do you want to host your project on Tina Cloud or self-host? (With self-hosting, the graphql api, auth and database will be hosted on your own server.)"
4290
+ message: "Do you want to host your project on TinaCloud or self-host? (With self-hosting, the graphql api, auth and database will be hosted on your own server.)"
4304
4291
  }
4305
4292
  ]);
4306
4293
  return answers;