astro-tractstack 2.0.0-rc.5 → 2.0.0-rc.7
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/README.md +1 -1
- package/bin/create-tractstack.js +100 -38
- package/package.json +1 -1
- package/templates/src/components/Footer.astro +1 -1
- package/templates/src/components/edit/PanelSwitch.tsx +3 -8
- package/templates/src/components/edit/pane/AddPanePanel_new.tsx +1 -1
- package/templates/src/components/tenant/RegistrationForm.tsx +4 -2
- package/templates/src/pages/[...slug]/edit.astro +7 -1
- package/templates/src/pages/[...slug].astro +1 -1
- package/templates/src/pages/context/[...contextSlug]/edit.astro +7 -1
- package/templates/src/pages/context/[...contextSlug].astro +1 -1
- package/templates/src/utils/compositor/templateMarkdownStyles.ts +8 -0
- package/templates/src/utils/helpers.ts +1 -0
package/README.md
CHANGED
|
@@ -283,7 +283,7 @@ sudo ~/t8k/src/tractstack-go/pkg/scripts/t8k-uninstall.sh
|
|
|
283
283
|
|
|
284
284
|
## Support & Documentation
|
|
285
285
|
|
|
286
|
-
- **Documentation**: https://tractstack.org
|
|
286
|
+
- **Documentation**: https://tractstack.org
|
|
287
287
|
- **GitHub Issues**: https://github.com/AtRiskMedia/tractstack-go/issues
|
|
288
288
|
- **Email Support**: hello@tractstack.com
|
|
289
289
|
- **Community**: Join discussions about adaptive web experiences
|
package/bin/create-tractstack.js
CHANGED
|
@@ -29,7 +29,7 @@ function detectPackageManager() {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// Parse existing .env file
|
|
32
|
-
function
|
|
32
|
+
function getEnvState() {
|
|
33
33
|
const defaults = {
|
|
34
34
|
goBackend: 'http://localhost:8080',
|
|
35
35
|
tenantId: 'default',
|
|
@@ -37,8 +37,15 @@ function parseExistingEnv() {
|
|
|
37
37
|
enableMultiTenant: false,
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
+
const found = {
|
|
41
|
+
goBackend: false,
|
|
42
|
+
tenantId: false,
|
|
43
|
+
goBackendPath: false,
|
|
44
|
+
enableMultiTenant: false,
|
|
45
|
+
};
|
|
46
|
+
|
|
40
47
|
if (!existsSync('.env')) {
|
|
41
|
-
return defaults;
|
|
48
|
+
return { envDefaults: defaults, envState: found };
|
|
42
49
|
}
|
|
43
50
|
|
|
44
51
|
try {
|
|
@@ -50,7 +57,6 @@ function parseExistingEnv() {
|
|
|
50
57
|
if (line && !line.startsWith('#')) {
|
|
51
58
|
const [key, ...valueParts] = line.split('=');
|
|
52
59
|
if (key && valueParts.length > 0) {
|
|
53
|
-
// Remove surrounding quotes and trim
|
|
54
60
|
let value = valueParts.join('=').trim();
|
|
55
61
|
if (
|
|
56
62
|
(value.startsWith('"') && value.endsWith('"')) ||
|
|
@@ -64,18 +70,26 @@ function parseExistingEnv() {
|
|
|
64
70
|
});
|
|
65
71
|
|
|
66
72
|
return {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
envDefaults: {
|
|
74
|
+
goBackend: envVars.PUBLIC_GO_BACKEND || defaults.goBackend,
|
|
75
|
+
tenantId: envVars.PUBLIC_TENANTID || defaults.tenantId,
|
|
76
|
+
goBackendPath:
|
|
77
|
+
envVars.PRIVATE_GO_BACKEND_PATH || defaults.goBackendPath,
|
|
78
|
+
enableMultiTenant:
|
|
79
|
+
envVars.ENABLE_MULTI_TENANT === 'true' || defaults.enableMultiTenant,
|
|
80
|
+
},
|
|
81
|
+
envState: {
|
|
82
|
+
goBackend: !!envVars.PUBLIC_GO_BACKEND,
|
|
83
|
+
tenantId: !!envVars.PUBLIC_TENANTID,
|
|
84
|
+
goBackendPath: !!envVars.PRIVATE_GO_BACKEND_PATH,
|
|
85
|
+
enableMultiTenant: !!envVars.ENABLE_MULTI_TENANT,
|
|
86
|
+
},
|
|
73
87
|
};
|
|
74
88
|
} catch (error) {
|
|
75
89
|
console.log(
|
|
76
90
|
kleur.yellow('⚠️ Found .env file but could not parse it, using defaults')
|
|
77
91
|
);
|
|
78
|
-
return defaults;
|
|
92
|
+
return { envDefaults: defaults, envState: found };
|
|
79
93
|
}
|
|
80
94
|
}
|
|
81
95
|
|
|
@@ -141,7 +155,7 @@ ${kleur.bold('Examples:')}
|
|
|
141
155
|
}
|
|
142
156
|
|
|
143
157
|
// Parse existing .env values
|
|
144
|
-
const envDefaults =
|
|
158
|
+
const { envDefaults, envState } = getEnvState();
|
|
145
159
|
const hasExistingEnv = existsSync('.env');
|
|
146
160
|
|
|
147
161
|
if (hasExistingEnv) {
|
|
@@ -152,9 +166,11 @@ ${kleur.bold('Examples:')}
|
|
|
152
166
|
);
|
|
153
167
|
}
|
|
154
168
|
|
|
155
|
-
//
|
|
156
|
-
const
|
|
157
|
-
|
|
169
|
+
// Build prompts array conditionally - only prompt for values not in .env
|
|
170
|
+
const promptQuestions = [];
|
|
171
|
+
|
|
172
|
+
if (!envState.goBackend) {
|
|
173
|
+
promptQuestions.push({
|
|
158
174
|
type: 'text',
|
|
159
175
|
name: 'goBackend',
|
|
160
176
|
message: 'TractStack Go backend URL:',
|
|
@@ -167,21 +183,46 @@ ${kleur.bold('Examples:')}
|
|
|
167
183
|
return 'Please enter a valid URL';
|
|
168
184
|
}
|
|
169
185
|
},
|
|
170
|
-
}
|
|
171
|
-
|
|
186
|
+
});
|
|
187
|
+
} else {
|
|
188
|
+
console.log(
|
|
189
|
+
kleur.green(`✓ Using Go backend URL: ${envDefaults.goBackend}`)
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (!envState.enableMultiTenant && !enableMultiTenant) {
|
|
194
|
+
promptQuestions.push({
|
|
172
195
|
type: 'confirm',
|
|
173
196
|
name: 'enableMultiTenant',
|
|
174
197
|
message: 'Enable multi-tenant functionality?',
|
|
175
198
|
initial: enableMultiTenant || envDefaults.enableMultiTenant,
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
199
|
+
});
|
|
200
|
+
} else {
|
|
201
|
+
const willEnable = enableMultiTenant || envDefaults.enableMultiTenant;
|
|
202
|
+
console.log(
|
|
203
|
+
kleur.green(
|
|
204
|
+
`✓ Multi-tenant functionality: ${willEnable ? 'enabled' : 'disabled'}`
|
|
205
|
+
)
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Only prompt for tenantId if multi-tenant will be enabled and tenantId not in .env
|
|
210
|
+
const willEnableMultiTenant =
|
|
211
|
+
enableMultiTenant || envDefaults.enableMultiTenant;
|
|
212
|
+
if (willEnableMultiTenant && !envState.tenantId) {
|
|
213
|
+
promptQuestions.push({
|
|
214
|
+
type: 'text',
|
|
179
215
|
name: 'tenantId',
|
|
180
216
|
message: 'Tenant ID:',
|
|
181
217
|
initial: envDefaults.tenantId,
|
|
182
218
|
validate: (value) => value.length > 0 || 'Tenant ID is required',
|
|
183
|
-
}
|
|
184
|
-
|
|
219
|
+
});
|
|
220
|
+
} else if (willEnableMultiTenant) {
|
|
221
|
+
console.log(kleur.green(`✓ Using Tenant ID: ${envDefaults.tenantId}`));
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (!envState.goBackendPath) {
|
|
225
|
+
promptQuestions.push({
|
|
185
226
|
type: 'text',
|
|
186
227
|
name: 'goBackendPath',
|
|
187
228
|
message: 'TractStack Go backend path:',
|
|
@@ -192,37 +233,58 @@ ${kleur.bold('Examples:')}
|
|
|
192
233
|
}
|
|
193
234
|
return true;
|
|
194
235
|
},
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
236
|
+
});
|
|
237
|
+
} else {
|
|
238
|
+
console.log(
|
|
239
|
+
kleur.green(`✓ Using Go backend path: ${envDefaults.goBackendPath}`)
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Always ask about examples (not stored in .env)
|
|
244
|
+
promptQuestions.push({
|
|
245
|
+
type: 'confirm',
|
|
246
|
+
name: 'includeExamples',
|
|
247
|
+
message:
|
|
248
|
+
'Include CodeHook examples? (custom components, collections route)',
|
|
249
|
+
initial: includeExamples,
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// Run prompts only if there are questions
|
|
253
|
+
const responses =
|
|
254
|
+
promptQuestions.length > 0 ? await prompts(promptQuestions) : {};
|
|
255
|
+
|
|
256
|
+
// Merge responses with env defaults for final values
|
|
257
|
+
const finalResponses = {
|
|
258
|
+
goBackend: responses.goBackend || envDefaults.goBackend,
|
|
259
|
+
enableMultiTenant:
|
|
260
|
+
responses.enableMultiTenant ??
|
|
261
|
+
(enableMultiTenant || envDefaults.enableMultiTenant),
|
|
262
|
+
tenantId: responses.tenantId || envDefaults.tenantId,
|
|
263
|
+
goBackendPath: responses.goBackendPath || envDefaults.goBackendPath,
|
|
264
|
+
includeExamples: responses.includeExamples ?? includeExamples,
|
|
265
|
+
};
|
|
204
266
|
|
|
205
|
-
if (!
|
|
206
|
-
console.log(kleur.red('\n
|
|
267
|
+
if (!finalResponses.goBackend) {
|
|
268
|
+
console.log(kleur.red('\n✗ Setup cancelled.'));
|
|
207
269
|
process.exit(1);
|
|
208
270
|
}
|
|
209
271
|
|
|
210
272
|
// Use existing tenantId if multi-tenant is disabled
|
|
211
|
-
const finalTenantId =
|
|
212
|
-
?
|
|
273
|
+
const finalTenantId = finalResponses.enableMultiTenant
|
|
274
|
+
? finalResponses.tenantId
|
|
213
275
|
: envDefaults.tenantId;
|
|
214
276
|
|
|
215
277
|
if (!finalTenantId) {
|
|
216
|
-
console.log(kleur.red('\n
|
|
278
|
+
console.log(kleur.red('\n✗ Setup cancelled - Tenant ID is required.'));
|
|
217
279
|
process.exit(1);
|
|
218
280
|
}
|
|
219
281
|
|
|
220
282
|
// Create .env file
|
|
221
283
|
const envContent = `# TractStack Configuration
|
|
222
|
-
PUBLIC_GO_BACKEND="${
|
|
284
|
+
PUBLIC_GO_BACKEND="${finalResponses.goBackend}"
|
|
223
285
|
PUBLIC_TENANTID="${finalTenantId}"
|
|
224
|
-
PRIVATE_GO_BACKEND_PATH="${
|
|
225
|
-
${
|
|
286
|
+
PRIVATE_GO_BACKEND_PATH="${finalResponses.goBackendPath.endsWith('/') ? finalResponses.goBackendPath : finalResponses.goBackendPath + '/'}"
|
|
287
|
+
ENABLE_MULTI_TENANT="${finalResponses.enableMultiTenant ? 'true' : 'false'}"
|
|
226
288
|
`;
|
|
227
289
|
|
|
228
290
|
try {
|
package/package.json
CHANGED
|
@@ -176,7 +176,7 @@ const createdDate = created ? new Date(created) : new Date();
|
|
|
176
176
|
>
|
|
177
177
|
Tract Stack</a
|
|
178
178
|
>
|
|
179
|
-
–
|
|
179
|
+
– the “free web press” by{` `}
|
|
180
180
|
<a
|
|
181
181
|
href="https://atriskmedia.com/?utm_source=tractstack&utm_medium=www&utm_campaign=community"
|
|
182
182
|
class="font-bold underline hover:text-black"
|
|
@@ -110,13 +110,9 @@ const PanelSwitch = ({
|
|
|
110
110
|
break;
|
|
111
111
|
|
|
112
112
|
case 'style-parent-add':
|
|
113
|
-
if (markdownNode
|
|
113
|
+
if (markdownNode)
|
|
114
114
|
return (
|
|
115
|
-
<StyleParentAddPanel
|
|
116
|
-
node={markdownNode}
|
|
117
|
-
layer={signal.layer || 0}
|
|
118
|
-
className={signal.className}
|
|
119
|
-
/>
|
|
115
|
+
<StyleParentAddPanel node={markdownNode} layer={signal.layer || 0} />
|
|
120
116
|
);
|
|
121
117
|
break;
|
|
122
118
|
|
|
@@ -200,12 +196,11 @@ const PanelSwitch = ({
|
|
|
200
196
|
break;
|
|
201
197
|
|
|
202
198
|
case 'style-element-add':
|
|
203
|
-
if (clickedNode && markdownNode
|
|
199
|
+
if (clickedNode && markdownNode)
|
|
204
200
|
return (
|
|
205
201
|
<StyleElementAddPanel
|
|
206
202
|
node={clickedNode}
|
|
207
203
|
parentNode={markdownNode}
|
|
208
|
-
className={signal.className}
|
|
209
204
|
onTitleChange={onTitleChange}
|
|
210
205
|
/>
|
|
211
206
|
);
|
|
@@ -493,7 +493,7 @@ const AddPaneNewPanel = ({
|
|
|
493
493
|
<Switch.HiddenInput />
|
|
494
494
|
<div className="flex h-6 items-center">
|
|
495
495
|
<Switch.Label className="px-4 text-sm text-gray-700">
|
|
496
|
-
|
|
496
|
+
Toggle subtle variation (great for stacking content)
|
|
497
497
|
</Switch.Label>
|
|
498
498
|
</div>
|
|
499
499
|
</Switch.Root>
|
|
@@ -291,11 +291,13 @@ export default function RegistrationForm({
|
|
|
291
291
|
value={state.email}
|
|
292
292
|
onChange={(value) => updateField('email', value)}
|
|
293
293
|
type="email"
|
|
294
|
-
placeholder="
|
|
294
|
+
placeholder="susie@amazing.com"
|
|
295
295
|
error={errors.email}
|
|
296
296
|
/>
|
|
297
297
|
<p className="mt-1 text-sm text-gray-500">
|
|
298
|
-
|
|
298
|
+
{isInitMode
|
|
299
|
+
? `Used for password reset, etc.`
|
|
300
|
+
: `You'll receive an activation email at this address`}
|
|
299
301
|
</p>
|
|
300
302
|
</div>
|
|
301
303
|
|
|
@@ -168,7 +168,13 @@ for (const [key, value] of Astro.url.searchParams) {
|
|
|
168
168
|
<StoryKeepToolMode isContext={false} client:only="react" />
|
|
169
169
|
|
|
170
170
|
<!-- Main Content Area -->
|
|
171
|
-
<main
|
|
171
|
+
<main
|
|
172
|
+
id="mainContent"
|
|
173
|
+
class="relative flex-1"
|
|
174
|
+
style={{
|
|
175
|
+
paddingBottom: 'var(--bottom-right-controls-bottom-offset, 16px)',
|
|
176
|
+
}}
|
|
177
|
+
>
|
|
172
178
|
<div class="bg-myblue/20 bg-mylightgrey h-full p-1.5">
|
|
173
179
|
<div
|
|
174
180
|
class="h-fit min-h-screen"
|
|
@@ -116,7 +116,7 @@ if (!brandConfig.SITE_INIT) {
|
|
|
116
116
|
impressions={storyData.impressions || []}
|
|
117
117
|
storyfragmentId={storyfragmentId}
|
|
118
118
|
>
|
|
119
|
-
<main id="main-content" class="
|
|
119
|
+
<main id="main-content" class="w-full">
|
|
120
120
|
<div class="panes-container">
|
|
121
121
|
{
|
|
122
122
|
paneIds.map((paneId: string) => (
|
|
@@ -159,7 +159,13 @@ for (const [key, value] of Astro.url.searchParams) {
|
|
|
159
159
|
<StoryKeepToolMode isContext={true} client:only="react" />
|
|
160
160
|
|
|
161
161
|
<!-- Main Content Area -->
|
|
162
|
-
<main
|
|
162
|
+
<main
|
|
163
|
+
id="mainContent"
|
|
164
|
+
class="relative flex-1"
|
|
165
|
+
style={{
|
|
166
|
+
paddingBottom: 'var(--bottom-right-controls-bottom-offset, 16px)',
|
|
167
|
+
}}
|
|
168
|
+
>
|
|
163
169
|
<div class="bg-myblue/20 bg-mylightgrey h-full p-1.5">
|
|
164
170
|
<div
|
|
165
171
|
class="h-fit min-h-screen"
|
|
@@ -112,7 +112,7 @@ if (!brandConfig.SITE_INIT) {
|
|
|
112
112
|
brandConfig={brandConfig}
|
|
113
113
|
storyfragmentId={paneId}
|
|
114
114
|
>
|
|
115
|
-
<main id="main-content" class="
|
|
115
|
+
<main id="main-content" class="w-full">
|
|
116
116
|
<div
|
|
117
117
|
id={`pane-${paneId}`}
|
|
118
118
|
data-pane-id={paneId}
|
|
@@ -359,6 +359,7 @@ export function getJustCopyDesign(
|
|
|
359
359
|
baseClasses[2].mobile.textWRAP = 'pretty';
|
|
360
360
|
baseClasses[2].mobile.maxW = '3xl';
|
|
361
361
|
if (bordered) {
|
|
362
|
+
baseClasses[2].mobile.rounded = 'lg';
|
|
362
363
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
363
364
|
{
|
|
364
365
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -383,6 +384,7 @@ export function getJustCopyDesign(
|
|
|
383
384
|
baseClasses[2].mobile.textALIGN = 'center';
|
|
384
385
|
baseClasses[2].mobile.textWRAP = 'balance';
|
|
385
386
|
if (bordered) {
|
|
387
|
+
baseClasses[2].mobile.rounded = 'lg';
|
|
386
388
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
387
389
|
{
|
|
388
390
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -405,6 +407,7 @@ export function getJustCopyDesign(
|
|
|
405
407
|
baseClasses[2].mobile.textALIGN = 'left';
|
|
406
408
|
baseClasses[2].mobile.textWRAP = 'pretty';
|
|
407
409
|
if (bordered) {
|
|
410
|
+
baseClasses[2].mobile.rounded = 'lg';
|
|
408
411
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
409
412
|
{
|
|
410
413
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -503,6 +506,7 @@ export function getSubTitleDesign(
|
|
|
503
506
|
baseClasses[2].mobile.textWRAP = 'pretty';
|
|
504
507
|
baseClasses[2].mobile.maxW = '3xl';
|
|
505
508
|
if (bordered) {
|
|
509
|
+
baseClasses[2].mobile.rounded = 'lg';
|
|
506
510
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
507
511
|
{
|
|
508
512
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -552,6 +556,7 @@ export function getSubTitleDesign(
|
|
|
552
556
|
baseClasses[2].mobile.textALIGN = 'center';
|
|
553
557
|
baseClasses[2].mobile.textWRAP = 'balance';
|
|
554
558
|
if (bordered) {
|
|
559
|
+
baseClasses[2].mobile.rounded = 'lg';
|
|
555
560
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
556
561
|
{
|
|
557
562
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -647,6 +652,7 @@ export function getSubTitleDesign(
|
|
|
647
652
|
baseClasses[2].mobile.textALIGN = 'center';
|
|
648
653
|
baseClasses[2].mobile.textWRAP = 'balance';
|
|
649
654
|
if (bordered) {
|
|
655
|
+
baseClasses[2].mobile.rounded = 'lg';
|
|
650
656
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
651
657
|
{
|
|
652
658
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -741,6 +747,7 @@ export function getSubTitleDesign(
|
|
|
741
747
|
baseClasses[2].mobile.textALIGN = 'left';
|
|
742
748
|
baseClasses[2].mobile.textWRAP = 'pretty';
|
|
743
749
|
if (bordered) {
|
|
750
|
+
baseClasses[2].mobile.rounded = 'lg';
|
|
744
751
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
745
752
|
{
|
|
746
753
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -986,6 +993,7 @@ export const getIntroDesign = (
|
|
|
986
993
|
(parentClasses[2].mobile.textALIGN = 'center');
|
|
987
994
|
parentClasses[2].mobile.textWRAP = 'balance';
|
|
988
995
|
if (bordered) {
|
|
996
|
+
parentClasses[2].mobile.rounded = 'lg';
|
|
989
997
|
parentClasses[2].mobile.bgCOLOR = getColor(
|
|
990
998
|
{
|
|
991
999
|
light: useOdd ? 'brand-2' : 'white',
|