Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/migrate-docs-links-to-aliases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@tinacms/cli": patch
"@tinacms/graphql": patch
"create-tina-app": patch
"tinacms": patch
---

Migrate docs links in shipped package code from raw `tina.io/docs/<path>` URLs to aliased `tina.io/docs/r/<alias>` URLs so the links survive future docs restructuring.
5 changes: 5 additions & 0 deletions .changeset/radio-groups-look-like-radios.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tinacms": patch
---

Fix the radio-group field styling so radio options render with a circular indicator and no longer look disabled when unselected.
5 changes: 5 additions & 0 deletions .changeset/tender-wombats-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tinacms/cli": patch
---

Add `--content=local` flag to `tinacms build` for fast production builds that source content from local disk while keeping the generated client pointed at TinaCloud (so SSR/ISR routes still work at runtime). Validates against TinaCloud and forces `NODE_ENV=production` for chained sub-commands.
4 changes: 2 additions & 2 deletions packages/@tinacms/cli/src/cmds/forestry-migrate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const transformForestryMatchToTinaMatch = (match: string) => {
if (match !== newMatch) {
logger.info(
`Info: Match ${match} was transformed to ${newMatch}. See ${linkText(
'https://tina.io/docs/forestry/common-errors/#info-match-match-was-transformed-to-newmatch'
'https://tina.io/docs/r/forestry-common-errors#info-match-match-was-transformed-to-newmatch'
)}`
);
}
Expand Down Expand Up @@ -262,7 +262,7 @@ const generateCollectionFromForestrySection = (args: {
`No templates found for section ${
section.label
}. Please see ${linkText(
'https://tina.io/docs/forestry/content-modelling/'
'https://tina.io/docs/r/forestry-content-modelling'
)} for more information`
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class ErrorSingleton {
});
logger.error(
`If you wish to edit any of the following templates, you will have to update your content and code to use the new name. See ${linkText(
'https://tina.io/docs/forestry/common-errors/#migrating-fields-with-non-alphanumeric-characters'
'https://tina.io/docs/r/forestry-common-errors#migrating-fields-with-non-alphanumeric-characters'
)} for more information.`
);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/@tinacms/cli/src/cmds/init/apply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ async function apply({
if (config.framework.name === 'other' && config.hosting === 'self-host') {
logger.error(
logText(
'Self-hosted Tina requires init setup only works with next.js right now. Please check out the docs for info on how to setup Tina on another framework: https://tina.io/docs/self-hosted/existing-site/'
'Self-hosted Tina requires init setup only works with next.js right now. Please check out the docs for info on how to setup Tina on another framework: https://tina.io/docs/r/self-hosting-nextjs'
)
);
return;
Expand Down Expand Up @@ -545,7 +545,7 @@ const logNextSteps = ({
logger.info(indentText(envFileText));
}
logger.info(
'Before you can run your site you will need to update it to use the backend client.\nSee docs for more info: https://tina.io/docs/self-hosted/querying-data/'
'Before you can run your site you will need to update it to use the backend client.\nSee docs for more info: https://tina.io/docs/r/self-hosted-querying-data'
);
logger.info(
'If you are deploying to vercel make sure to add the environment variables to your project.'
Expand Down
2 changes: 1 addition & 1 deletion packages/@tinacms/cli/src/cmds/init/printFinalMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function successMessage(ctx: any, next: () => void, options) {

logger.info(`${chalk.bold('Read the docs')}`);
logger.info(
` Check out 'https://tina.io/docs/introduction/tina-init/#adding-tina' for help getting started with Tina \n`
` Check out 'https://tina.io/docs/r/tina-init#adding-tina' for help getting started with Tina \n`
);

logger.info(`Enjoy Tina! 🦙`);
Expand Down
27 changes: 21 additions & 6 deletions packages/@tinacms/cli/src/next/codegen/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,22 @@ export class Codegen {
localUrl: string;
// production url
productionUrl: string;
// URL for the local GraphQL server used during --content=local builds
localBuildUrl?: string;
graphqlSchemaDoc: DocumentNode;
tinaSchema: TinaSchema;
lookup: any;
noClientBuildCache: boolean;
// When true, queries run locally but the generated client points to TinaCloud
localContentBuild: boolean;

constructor({
configManager,
port,
queryDoc,
fragDoc,
isLocal,
localContentBuild,
graphqlSchemaDoc,
tinaSchema,
lookup,
Expand All @@ -45,12 +50,14 @@ export class Codegen {
queryDoc: string;
fragDoc: string;
isLocal: boolean;
localContentBuild?: boolean;
graphqlSchemaDoc: DocumentNode;
tinaSchema: TinaSchema;
lookup: any;
noClientBuildCache: boolean;
}) {
this.isLocal = isLocal;
this.localContentBuild = localContentBuild || false;
this.graphqlSchemaDoc = graphqlSchemaDoc;
this.configManager = configManager;
this.port = port;
Expand Down Expand Up @@ -112,10 +119,12 @@ export class Codegen {
// update _lookup.json
await this.writeConfigFile('_lookup.json', JSON.stringify(this.lookup));

const { apiURL, localUrl, tinaCloudUrl } = this._createApiUrl();
const { apiURL, localUrl, tinaCloudUrl, localBuildUrl } =
this._createApiUrl();
this.apiURL = apiURL;
this.localUrl = localUrl;
this.productionUrl = tinaCloudUrl;
this.localBuildUrl = localBuildUrl;

if (this.configManager.shouldSkipSDK()) {
await this.removeGeneratedFilesIfExists();
Expand Down Expand Up @@ -235,16 +244,22 @@ export class Codegen {
let localUrl = `http://localhost:${this.port}/graphql`;
let tinaCloudUrl = `${baseUrl}/${version}/content/${clientId}/github/${branch}`;

let apiURL = this.isLocal
? `http://localhost:${this.port}/graphql`
: `${baseUrl}/${version}/content/${clientId}/github/${branch}`;
let apiURL: string;
if (this.isLocal && !this.localContentBuild) {
apiURL = `http://localhost:${this.port}/graphql`;
} else {
apiURL = `${baseUrl}/${version}/content/${clientId}/github/${branch}`;
}

if (this.configManager.config.contentApiUrlOverride) {
apiURL = this.configManager.config.contentApiUrlOverride;
localUrl = apiURL;
tinaCloudUrl = apiURL;
}
return { apiURL, localUrl, tinaCloudUrl };
const localBuildUrl = this.port
? `http://localhost:${this.port}/graphql`
: undefined;
return { apiURL, localUrl, tinaCloudUrl, localBuildUrl };
}

getApiURL() {
Expand Down Expand Up @@ -357,7 +372,7 @@ export const client = createClient({ ${
this.configManager.generatedCachePath
)}', `
: ''
}url: '${apiURL}', token: '${token}', queries, ${
}url: ${this.localContentBuild ? `process.env.TINA_LOCAL_URL || '${apiURL}'` : `'${apiURL}'`}, token: '${token}', queries, ${
errorPolicy ? `errorPolicy: '${errorPolicy}'` : ''
} });
export default client;
Expand Down
77 changes: 65 additions & 12 deletions packages/@tinacms/cli/src/next/commands/build-command/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ export class BuildCommand extends BaseCommand {
description:
'Starts local Graphql server and builds the local client instead of production client',
});
contentOption = Option.String('--content', {
description:
'Source for content during the build. Use `--content=local` to build from local content for fast builds while still generating a production client that connects to TinaCloud when deployed.',
});
skipIndexing = Option.Boolean('--skip-indexing', false, {
description:
'Skips indexing the content. This can be used for building the site without indexing the content (defaults to false)',
Expand Down Expand Up @@ -109,6 +113,16 @@ export class BuildCommand extends BaseCommand {
process.exit(1);
}

if (this.contentOption !== undefined && this.contentOption !== 'local') {
logger.error(
`${dangerText(
`ERROR: --content only accepts 'local'. Received '${this.contentOption}'.`
)}`
);
process.exit(1);
}
const localContentOnly = this.contentOption === 'local';

try {
await configManager.processConfig();
} catch (e) {
Expand All @@ -118,6 +132,21 @@ export class BuildCommand extends BaseCommand {
);
process.exit(1);
}
if (localContentOnly && !this.localOption) {
const config = configManager.config;
const missing = [];
if (!config.branch) missing.push('branch');
if (!config.clientId) missing.push('clientId');
if (!config.token) missing.push('token');
if (missing.length > 0) {
logger.error(
`${dangerText(
`ERROR: --content=local requires ${missing.join(', ')} to be configured, since the generated client must point to TinaCloud.`
)}`
);
process.exit(1);
}
}
let server: ViteDevServer | undefined;
// Initialize the host TCP server
createDBServer(Number(this.datalayerPort));
Expand All @@ -129,10 +158,12 @@ export class BuildCommand extends BaseCommand {
const { queryDoc, fragDoc, graphQLSchema, tinaSchema, lookup } =
await buildSchema(configManager.config);

const useLocalServer = this.localOption || localContentOnly;
const codegen = new Codegen({
configManager: configManager,
port: this.localOption ? Number(this.port) : undefined,
isLocal: this.localOption,
port: useLocalServer ? Number(this.port) : undefined,
isLocal: useLocalServer,
localContentBuild: localContentOnly && !this.localOption,
queryDoc,
fragDoc,
graphqlSchemaDoc: graphQLSchema,
Expand All @@ -142,15 +173,18 @@ export class BuildCommand extends BaseCommand {
});
const apiURL = await codegen.execute();

// Always index the content if we are building locally (and not skipping indexing)
// Always index the content when we're sourcing it locally (and not skipping indexing)
if (
(configManager.hasSelfHostedConfig() || this.localOption) &&
(configManager.hasSelfHostedConfig() ||
this.localOption ||
localContentOnly) &&
!this.skipIndexing
) {
// if we are building locally use the default spinner text
const text = this.localOption
? undefined
: 'Indexing to self-hosted data layer';
// if we are sourcing content locally use the default spinner text
const text =
this.localOption || localContentOnly
? undefined
: 'Indexing to self-hosted data layer';
try {
await this.indexContentWithSpinner({
text,
Expand All @@ -169,13 +203,14 @@ export class BuildCommand extends BaseCommand {
}
}

if (this.localOption) {
// start the dev server if we are building locally
if (this.localOption || localContentOnly) {
// start the local GraphQL server whenever content is sourced locally
const serverUrl = codegen.localBuildUrl || apiURL;
server = await createDevServer(
configManager,
database,
null,
apiURL,
serverUrl,
true,
(lockedFn) => lockedFn()
);
Expand Down Expand Up @@ -254,10 +289,20 @@ export class BuildCommand extends BaseCommand {
'index.html\nassets/'
);

if (
localContentOnly &&
configManager.config.search &&
!this.skipSearchIndex
) {
logger.warn(
`${warnText('WARN: Search indexing skipped when building with --content=local. The search index on TinaCloud was not updated.')}`
);
}
if (
configManager.config.search &&
!this.skipSearchIndex &&
!this.localOption
!this.localOption &&
!localContentOnly
) {
let client: SearchClient;
const hasTinaSearch = Boolean(configManager.config?.search?.tina);
Expand Down Expand Up @@ -364,6 +409,14 @@ export class BuildCommand extends BaseCommand {
...summaryItems,
],
});
if (localContentOnly && codegen.localBuildUrl) {
process.env.TINA_LOCAL_URL = codegen.localBuildUrl;
// Ensure the sub-command runs with NODE_ENV=production so frameworks
// like Next.js produce a production build
if (!process.env.NODE_ENV || process.env.NODE_ENV !== 'production') {
process.env.NODE_ENV = 'production';
}
}
if (this.subCommand) {
await this.startSubCommand();
} else {
Expand Down
4 changes: 2 additions & 2 deletions packages/@tinacms/graphql/src/database/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ export const scanAllContent = async (
.map((collection) => `"${collection}"`)
.join(
', '
)}. This can cause unexpected behavior. We recommend updating the \`match\` property of those collections so that each file is in only one collection.\nThis will be an error in the future. See https://tina.io/docs/errors/file-in-mutpliple-collections/\n`
)}. This can cause unexpected behavior. We recommend updating the \`match\` property of those collections so that each file is in only one collection.\nThis will be an error in the future. See https://tina.io/docs/r/content-modelling-collections#path-matching\n`
);
});

Expand Down Expand Up @@ -391,7 +391,7 @@ export const loadAndParseWithAliases = async (
const template = getTemplateForFile(templateInfo, data as any);
if (!template) {
console.warn(
`Document: ${filepath} has an ambiguous template, skipping from indexing. See https://tina.io/docs/errors/ambiguous-template/ for more info.`
`Document: ${filepath} has an ambiguous template, skipping from indexing. See https://tina.io/docs/r/ambiguous-template for more info.`
);
return;
}
Expand Down
8 changes: 4 additions & 4 deletions packages/create-tina-app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -512,22 +512,22 @@ export async function run() {
console.log('Next steps:');
console.log(
` • 📝 Edit some content: ${TextStyles.link(
'https://tina.io/docs/using-tina-editor'
'https://tina.io/docs/r/using-tina-editor'
)}`
);
console.log(
` • 📖 Learn the basics: ${TextStyles.link(
'https://tina.io/docs/schema/'
'https://tina.io/docs/r/content-modelling-collections'
)}`
);
console.log(
` • 🖌️ Extend Tina with custom field components: ${TextStyles.link(
'https://tina.io/docs/advanced/extending-tina/'
'https://tina.io/docs/r/custom-fields-react'
)}`
);
console.log(
` • 🚀 Deploy to Production: ${TextStyles.link(
'https://tina.io/docs/tinacloud/'
'https://tina.io/docs/r/what-is-tinacloud'
)}`
);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/tinacms/src/admin/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ const CheckSchema = ({

If you just pushed changes to the branch, try pulling the latest changes.

For more information, please see https://tina.io/docs/tinacloud/troubleshooting`
For more information, please see https://tina.io/docs/r/troubleshooting`
);
}
})
Expand Down
Loading
Loading