create-objectstack 6.1.1 → 6.3.0
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 +167 -569
- package/dist/templates/blank/README.md +27 -0
- package/dist/templates/blank/objectstack.config.ts +19 -0
- package/dist/templates/blank/objectstack.manifest.json +16 -0
- package/dist/templates/blank/package.json +23 -0
- package/dist/templates/blank/src/objects/index.ts +1 -0
- package/dist/templates/blank/src/objects/note.object.ts +28 -0
- package/dist/templates/blank/tsconfig.json +15 -0
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -3,554 +3,46 @@ import { Command } from "commander";
|
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import fs from "fs";
|
|
5
5
|
import path from "path";
|
|
6
|
+
import os from "os";
|
|
6
7
|
import { execSync } from "child_process";
|
|
7
8
|
import { fileURLToPath } from "url";
|
|
9
|
+
import { pipeline } from "stream/promises";
|
|
10
|
+
import { createGunzip } from "zlib";
|
|
11
|
+
import { createWriteStream, createReadStream } from "fs";
|
|
12
|
+
import { mkdtemp, rm } from "fs/promises";
|
|
13
|
+
import * as tar from "tar";
|
|
8
14
|
var __filename = fileURLToPath(import.meta.url);
|
|
9
15
|
var __dirname = path.dirname(__filename);
|
|
10
|
-
var
|
|
16
|
+
var BUNDLED_TEMPLATES_DIR = path.resolve(__dirname, "templates");
|
|
17
|
+
var REMOTE_REPO = "objectstack-ai/templates";
|
|
18
|
+
var REMOTE_BRANCH = "main";
|
|
19
|
+
var REMOTE_TARBALL_URL = `https://codeload.github.com/${REMOTE_REPO}/tar.gz/refs/heads/${REMOTE_BRANCH}`;
|
|
11
20
|
var TEMPLATES = {
|
|
12
|
-
|
|
13
|
-
description: "
|
|
14
|
-
|
|
15
|
-
"objectstack.config.ts": (name) => `import { defineStack } from '@objectstack/spec';
|
|
16
|
-
import * as objects from './src/objects';
|
|
17
|
-
|
|
18
|
-
export default defineStack({
|
|
19
|
-
manifest: {
|
|
20
|
-
id: 'com.example.${name}',
|
|
21
|
-
namespace: '${name}',
|
|
22
|
-
version: '0.1.0',
|
|
23
|
-
type: 'app',
|
|
24
|
-
name: '${toTitleCase(name)}',
|
|
25
|
-
description: '${toTitleCase(name)} \u2014 built with ObjectStack',
|
|
21
|
+
blank: {
|
|
22
|
+
description: "Minimal starter \u2014 one object, REST API, ready to extend",
|
|
23
|
+
source: { kind: "bundled", dir: "blank" }
|
|
26
24
|
},
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
api: {
|
|
31
|
-
rest: { enabled: true, basePath: '/api' },
|
|
25
|
+
todo: {
|
|
26
|
+
description: "Universal task & project management starter",
|
|
27
|
+
source: { kind: "remote", pkg: "todo" }
|
|
32
28
|
},
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
name,
|
|
37
|
-
version: "0.1.0",
|
|
38
|
-
private: true,
|
|
39
|
-
type: "module",
|
|
40
|
-
scripts: {
|
|
41
|
-
dev: "objectstack dev",
|
|
42
|
-
start: "objectstack serve",
|
|
43
|
-
build: "objectstack compile",
|
|
44
|
-
validate: "objectstack validate",
|
|
45
|
-
typecheck: "tsc --noEmit"
|
|
46
|
-
},
|
|
47
|
-
dependencies: {
|
|
48
|
-
"@objectstack/spec": "^3.0.0",
|
|
49
|
-
"@objectstack/runtime": "^3.0.0",
|
|
50
|
-
"@objectstack/driver-memory": "^3.0.0",
|
|
51
|
-
"@objectstack/plugin-hono-server": "^3.0.0"
|
|
52
|
-
},
|
|
53
|
-
devDependencies: {
|
|
54
|
-
"@objectstack/cli": "^3.0.0",
|
|
55
|
-
"typescript": "^5.3.0"
|
|
56
|
-
}
|
|
57
|
-
}, null, 2) + "\n",
|
|
58
|
-
"tsconfig.json": () => JSON.stringify({
|
|
59
|
-
compilerOptions: {
|
|
60
|
-
target: "ES2022",
|
|
61
|
-
module: "ESNext",
|
|
62
|
-
moduleResolution: "bundler",
|
|
63
|
-
strict: true,
|
|
64
|
-
esModuleInterop: true,
|
|
65
|
-
skipLibCheck: true,
|
|
66
|
-
outDir: "dist",
|
|
67
|
-
rootDir: ".",
|
|
68
|
-
declaration: true
|
|
69
|
-
},
|
|
70
|
-
include: ["*.ts", "src/**/*"],
|
|
71
|
-
exclude: ["dist", "node_modules"]
|
|
72
|
-
}, null, 2) + "\n",
|
|
73
|
-
"src/objects/task.ts": () => `import * as Data from '@objectstack/spec/data';
|
|
74
|
-
|
|
75
|
-
const task: Data.Object = {
|
|
76
|
-
name: 'task',
|
|
77
|
-
label: 'Task',
|
|
78
|
-
ownership: 'own',
|
|
79
|
-
fields: {
|
|
80
|
-
title: {
|
|
81
|
-
type: 'text',
|
|
82
|
-
label: 'Title',
|
|
83
|
-
required: true,
|
|
84
|
-
},
|
|
85
|
-
description: {
|
|
86
|
-
type: 'textarea',
|
|
87
|
-
label: 'Description',
|
|
88
|
-
},
|
|
89
|
-
status: {
|
|
90
|
-
type: 'select',
|
|
91
|
-
label: 'Status',
|
|
92
|
-
options: [
|
|
93
|
-
{ label: 'Open', value: 'open' },
|
|
94
|
-
{ label: 'In Progress', value: 'in_progress' },
|
|
95
|
-
{ label: 'Done', value: 'done' },
|
|
96
|
-
],
|
|
97
|
-
defaultValue: 'open',
|
|
98
|
-
},
|
|
99
|
-
due_date: {
|
|
100
|
-
type: 'date',
|
|
101
|
-
label: 'Due Date',
|
|
102
|
-
},
|
|
29
|
+
compliance: {
|
|
30
|
+
description: "Compliance posture & evidence management (SOC2 / ISO27001)",
|
|
31
|
+
source: { kind: "remote", pkg: "compliance" }
|
|
103
32
|
},
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
`,
|
|
108
|
-
"src/objects/index.ts": () => `export { default as task } from './task';
|
|
109
|
-
`,
|
|
110
|
-
".gitignore": () => `node_modules/
|
|
111
|
-
dist/
|
|
112
|
-
*.tsbuildinfo
|
|
113
|
-
`,
|
|
114
|
-
"README.md": (name) => `# ${toTitleCase(name)}
|
|
115
|
-
|
|
116
|
-
Built with [ObjectStack](https://objectstack.com).
|
|
117
|
-
|
|
118
|
-
## Quick Start
|
|
119
|
-
|
|
120
|
-
\`\`\`bash
|
|
121
|
-
# Install dependencies
|
|
122
|
-
npm install
|
|
123
|
-
|
|
124
|
-
# Start development server
|
|
125
|
-
npm run dev
|
|
126
|
-
|
|
127
|
-
# Validate configuration
|
|
128
|
-
npm run validate
|
|
129
|
-
\`\`\`
|
|
130
|
-
|
|
131
|
-
## Project Structure
|
|
132
|
-
|
|
133
|
-
- \`objectstack.config.ts\` \u2014 Stack definition (objects, API, settings)
|
|
134
|
-
- \`src/objects/\` \u2014 Object definitions
|
|
135
|
-
- \`dist/\` \u2014 Compiled output
|
|
136
|
-
|
|
137
|
-
## Learn More
|
|
138
|
-
|
|
139
|
-
- [ObjectStack Documentation](https://objectstack.com/docs)
|
|
140
|
-
`
|
|
141
|
-
}
|
|
142
|
-
},
|
|
143
|
-
"full-stack": {
|
|
144
|
-
description: "Server + UI + auth + 3 CRM objects",
|
|
145
|
-
files: {
|
|
146
|
-
"objectstack.config.ts": (name) => `import { defineStack } from '@objectstack/spec';
|
|
147
|
-
import * as objects from './src/objects';
|
|
148
|
-
import * as apps from './src/apps';
|
|
149
|
-
|
|
150
|
-
export default defineStack({
|
|
151
|
-
manifest: {
|
|
152
|
-
id: 'com.example.${name}',
|
|
153
|
-
namespace: '${name}',
|
|
154
|
-
version: '0.1.0',
|
|
155
|
-
type: 'app',
|
|
156
|
-
name: '${toTitleCase(name)}',
|
|
157
|
-
description: '${toTitleCase(name)} CRM \u2014 built with ObjectStack',
|
|
33
|
+
content: {
|
|
34
|
+
description: "Content marketing pipeline \u2014 editorial calendar & channel ROI",
|
|
35
|
+
source: { kind: "remote", pkg: "content" }
|
|
158
36
|
},
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
api: {
|
|
164
|
-
rest: { enabled: true, basePath: '/api' },
|
|
37
|
+
contracts: {
|
|
38
|
+
description: "Post-signature CLM \u2014 approvals, obligations, renewals",
|
|
39
|
+
source: { kind: "remote", pkg: "contracts" }
|
|
165
40
|
},
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
name,
|
|
170
|
-
version: "0.1.0",
|
|
171
|
-
private: true,
|
|
172
|
-
type: "module",
|
|
173
|
-
scripts: {
|
|
174
|
-
dev: "objectstack dev",
|
|
175
|
-
start: "objectstack serve",
|
|
176
|
-
build: "objectstack compile",
|
|
177
|
-
validate: "objectstack validate",
|
|
178
|
-
typecheck: "tsc --noEmit"
|
|
179
|
-
},
|
|
180
|
-
dependencies: {
|
|
181
|
-
"@objectstack/spec": "^3.0.0",
|
|
182
|
-
"@objectstack/runtime": "^3.0.0",
|
|
183
|
-
"@objectstack/driver-memory": "^3.0.0",
|
|
184
|
-
"@objectstack/plugin-hono-server": "^3.0.0",
|
|
185
|
-
"@objectstack/plugin-auth": "^3.0.0"
|
|
186
|
-
},
|
|
187
|
-
devDependencies: {
|
|
188
|
-
"@objectstack/cli": "^3.0.0",
|
|
189
|
-
"typescript": "^5.3.0"
|
|
190
|
-
}
|
|
191
|
-
}, null, 2) + "\n",
|
|
192
|
-
"tsconfig.json": () => JSON.stringify({
|
|
193
|
-
compilerOptions: {
|
|
194
|
-
target: "ES2022",
|
|
195
|
-
module: "ESNext",
|
|
196
|
-
moduleResolution: "bundler",
|
|
197
|
-
strict: true,
|
|
198
|
-
esModuleInterop: true,
|
|
199
|
-
skipLibCheck: true,
|
|
200
|
-
outDir: "dist",
|
|
201
|
-
rootDir: ".",
|
|
202
|
-
declaration: true
|
|
203
|
-
},
|
|
204
|
-
include: ["*.ts", "src/**/*"],
|
|
205
|
-
exclude: ["dist", "node_modules"]
|
|
206
|
-
}, null, 2) + "\n",
|
|
207
|
-
"src/objects/contact.ts": () => `import * as Data from '@objectstack/spec/data';
|
|
208
|
-
|
|
209
|
-
const contact: Data.Object = {
|
|
210
|
-
name: 'contact',
|
|
211
|
-
label: 'Contact',
|
|
212
|
-
ownership: 'own',
|
|
213
|
-
fields: {
|
|
214
|
-
first_name: {
|
|
215
|
-
type: 'text',
|
|
216
|
-
label: 'First Name',
|
|
217
|
-
required: true,
|
|
218
|
-
},
|
|
219
|
-
last_name: {
|
|
220
|
-
type: 'text',
|
|
221
|
-
label: 'Last Name',
|
|
222
|
-
required: true,
|
|
223
|
-
},
|
|
224
|
-
email: {
|
|
225
|
-
type: 'text',
|
|
226
|
-
label: 'Email',
|
|
227
|
-
},
|
|
228
|
-
phone: {
|
|
229
|
-
type: 'text',
|
|
230
|
-
label: 'Phone',
|
|
231
|
-
},
|
|
232
|
-
company: {
|
|
233
|
-
type: 'lookup',
|
|
234
|
-
label: 'Company',
|
|
235
|
-
reference: 'company',
|
|
236
|
-
},
|
|
237
|
-
},
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
export default contact;
|
|
241
|
-
`,
|
|
242
|
-
"src/objects/company.ts": () => `import * as Data from '@objectstack/spec/data';
|
|
243
|
-
|
|
244
|
-
const company: Data.Object = {
|
|
245
|
-
name: 'company',
|
|
246
|
-
label: 'Company',
|
|
247
|
-
ownership: 'own',
|
|
248
|
-
fields: {
|
|
249
|
-
name: {
|
|
250
|
-
type: 'text',
|
|
251
|
-
label: 'Company Name',
|
|
252
|
-
required: true,
|
|
253
|
-
},
|
|
254
|
-
website: {
|
|
255
|
-
type: 'text',
|
|
256
|
-
label: 'Website',
|
|
257
|
-
},
|
|
258
|
-
industry: {
|
|
259
|
-
type: 'select',
|
|
260
|
-
label: 'Industry',
|
|
261
|
-
options: [
|
|
262
|
-
{ label: 'Technology', value: 'technology' },
|
|
263
|
-
{ label: 'Finance', value: 'finance' },
|
|
264
|
-
{ label: 'Healthcare', value: 'healthcare' },
|
|
265
|
-
{ label: 'Other', value: 'other' },
|
|
266
|
-
],
|
|
267
|
-
},
|
|
268
|
-
},
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
export default company;
|
|
272
|
-
`,
|
|
273
|
-
"src/objects/deal.ts": () => `import * as Data from '@objectstack/spec/data';
|
|
274
|
-
|
|
275
|
-
const deal: Data.Object = {
|
|
276
|
-
name: 'deal',
|
|
277
|
-
label: 'Deal',
|
|
278
|
-
ownership: 'own',
|
|
279
|
-
fields: {
|
|
280
|
-
name: {
|
|
281
|
-
type: 'text',
|
|
282
|
-
label: 'Deal Name',
|
|
283
|
-
required: true,
|
|
284
|
-
},
|
|
285
|
-
amount: {
|
|
286
|
-
type: 'number',
|
|
287
|
-
label: 'Amount',
|
|
288
|
-
},
|
|
289
|
-
stage: {
|
|
290
|
-
type: 'select',
|
|
291
|
-
label: 'Stage',
|
|
292
|
-
options: [
|
|
293
|
-
{ label: 'Prospecting', value: 'prospecting' },
|
|
294
|
-
{ label: 'Qualification', value: 'qualification' },
|
|
295
|
-
{ label: 'Proposal', value: 'proposal' },
|
|
296
|
-
{ label: 'Closed Won', value: 'closed_won' },
|
|
297
|
-
{ label: 'Closed Lost', value: 'closed_lost' },
|
|
298
|
-
],
|
|
299
|
-
defaultValue: 'prospecting',
|
|
300
|
-
},
|
|
301
|
-
contact: {
|
|
302
|
-
type: 'lookup',
|
|
303
|
-
label: 'Contact',
|
|
304
|
-
reference: 'contact',
|
|
305
|
-
},
|
|
306
|
-
company: {
|
|
307
|
-
type: 'lookup',
|
|
308
|
-
label: 'Company',
|
|
309
|
-
reference: 'company',
|
|
310
|
-
},
|
|
311
|
-
close_date: {
|
|
312
|
-
type: 'date',
|
|
313
|
-
label: 'Close Date',
|
|
314
|
-
},
|
|
315
|
-
},
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
export default deal;
|
|
319
|
-
`,
|
|
320
|
-
"src/objects/index.ts": () => `export { default as contact } from './contact';
|
|
321
|
-
export { default as company } from './company';
|
|
322
|
-
export { default as deal } from './deal';
|
|
323
|
-
`,
|
|
324
|
-
"src/views/contact_list.ts": () => `import * as UI from '@objectstack/spec/ui';
|
|
325
|
-
|
|
326
|
-
const contactList: UI.View = {
|
|
327
|
-
name: 'contact_list',
|
|
328
|
-
label: 'All Contacts',
|
|
329
|
-
object: 'contact',
|
|
330
|
-
type: 'list',
|
|
331
|
-
columns: ['first_name', 'last_name', 'email', 'phone', 'company'],
|
|
332
|
-
};
|
|
333
|
-
|
|
334
|
-
export default contactList;
|
|
335
|
-
`,
|
|
336
|
-
"src/views/company_list.ts": () => `import * as UI from '@objectstack/spec/ui';
|
|
337
|
-
|
|
338
|
-
const companyList: UI.View = {
|
|
339
|
-
name: 'company_list',
|
|
340
|
-
label: 'All Companies',
|
|
341
|
-
object: 'company',
|
|
342
|
-
type: 'list',
|
|
343
|
-
columns: ['name', 'website', 'industry'],
|
|
344
|
-
};
|
|
345
|
-
|
|
346
|
-
export default companyList;
|
|
347
|
-
`,
|
|
348
|
-
"src/views/deal_list.ts": () => `import * as UI from '@objectstack/spec/ui';
|
|
349
|
-
|
|
350
|
-
const dealList: UI.View = {
|
|
351
|
-
name: 'deal_list',
|
|
352
|
-
label: 'All Deals',
|
|
353
|
-
object: 'deal',
|
|
354
|
-
type: 'list',
|
|
355
|
-
columns: ['name', 'amount', 'stage', 'contact', 'close_date'],
|
|
356
|
-
};
|
|
357
|
-
|
|
358
|
-
export default dealList;
|
|
359
|
-
`,
|
|
360
|
-
"src/apps/crm.ts": () => `import * as UI from '@objectstack/spec/ui';
|
|
361
|
-
|
|
362
|
-
const crm: UI.App = {
|
|
363
|
-
name: 'crm',
|
|
364
|
-
label: 'CRM',
|
|
365
|
-
description: 'Customer Relationship Management',
|
|
366
|
-
navigation: [
|
|
367
|
-
{ type: 'object', object: 'contact', label: 'Contacts' },
|
|
368
|
-
{ type: 'object', object: 'company', label: 'Companies' },
|
|
369
|
-
{ type: 'object', object: 'deal', label: 'Deals' },
|
|
370
|
-
],
|
|
371
|
-
};
|
|
372
|
-
|
|
373
|
-
export default crm;
|
|
374
|
-
`,
|
|
375
|
-
"src/apps/index.ts": () => `export { default as crm } from './crm';
|
|
376
|
-
`,
|
|
377
|
-
".gitignore": () => `node_modules/
|
|
378
|
-
dist/
|
|
379
|
-
*.tsbuildinfo
|
|
380
|
-
`,
|
|
381
|
-
"README.md": (name) => `# ${toTitleCase(name)}
|
|
382
|
-
|
|
383
|
-
A full-stack CRM application built with [ObjectStack](https://objectstack.com).
|
|
384
|
-
|
|
385
|
-
## Quick Start
|
|
386
|
-
|
|
387
|
-
\`\`\`bash
|
|
388
|
-
npm install
|
|
389
|
-
npm run dev
|
|
390
|
-
\`\`\`
|
|
391
|
-
|
|
392
|
-
## Project Structure
|
|
393
|
-
|
|
394
|
-
- \`objectstack.config.ts\` \u2014 Stack definition
|
|
395
|
-
- \`src/objects/\` \u2014 Data objects (Contact, Company, Deal)
|
|
396
|
-
- \`src/views/\` \u2014 List views
|
|
397
|
-
- \`src/apps/crm.ts\` \u2014 CRM app with navigation
|
|
398
|
-
|
|
399
|
-
## Learn More
|
|
400
|
-
|
|
401
|
-
- [ObjectStack Documentation](https://objectstack.com/docs)
|
|
402
|
-
`
|
|
403
|
-
}
|
|
404
|
-
},
|
|
405
|
-
plugin: {
|
|
406
|
-
description: "Plugin skeleton with test setup",
|
|
407
|
-
files: {
|
|
408
|
-
"objectstack.config.ts": (name) => `import { defineStack } from '@objectstack/spec';
|
|
409
|
-
import * as objects from './src/objects';
|
|
410
|
-
|
|
411
|
-
export default defineStack({
|
|
412
|
-
manifest: {
|
|
413
|
-
id: 'com.objectstack.plugin-${name}',
|
|
414
|
-
namespace: 'plugin_${name}',
|
|
415
|
-
version: '0.1.0',
|
|
416
|
-
type: 'plugin',
|
|
417
|
-
name: '${toTitleCase(name)} Plugin',
|
|
418
|
-
description: 'ObjectStack Plugin: ${toTitleCase(name)}',
|
|
419
|
-
},
|
|
420
|
-
|
|
421
|
-
objects: Object.values(objects),
|
|
422
|
-
});
|
|
423
|
-
`,
|
|
424
|
-
"package.json": (name) => JSON.stringify({
|
|
425
|
-
name: `@objectstack/plugin-${name}`,
|
|
426
|
-
version: "0.1.0",
|
|
427
|
-
description: `ObjectStack Plugin: ${toTitleCase(name)}`,
|
|
428
|
-
main: "dist/index.js",
|
|
429
|
-
types: "dist/index.d.ts",
|
|
430
|
-
type: "module",
|
|
431
|
-
scripts: {
|
|
432
|
-
build: "tsc",
|
|
433
|
-
dev: "tsc --watch",
|
|
434
|
-
test: "vitest run",
|
|
435
|
-
validate: "objectstack validate",
|
|
436
|
-
typecheck: "tsc --noEmit"
|
|
437
|
-
},
|
|
438
|
-
keywords: ["objectstack", "plugin", name],
|
|
439
|
-
author: "",
|
|
440
|
-
license: "MIT",
|
|
441
|
-
dependencies: {
|
|
442
|
-
"@objectstack/spec": "^3.0.0"
|
|
443
|
-
},
|
|
444
|
-
devDependencies: {
|
|
445
|
-
"@types/node": "^22.0.0",
|
|
446
|
-
"typescript": "^5.3.0",
|
|
447
|
-
"vitest": "^4.0.0"
|
|
448
|
-
}
|
|
449
|
-
}, null, 2) + "\n",
|
|
450
|
-
"tsconfig.json": () => JSON.stringify({
|
|
451
|
-
compilerOptions: {
|
|
452
|
-
target: "ES2022",
|
|
453
|
-
module: "ESNext",
|
|
454
|
-
moduleResolution: "bundler",
|
|
455
|
-
strict: true,
|
|
456
|
-
esModuleInterop: true,
|
|
457
|
-
skipLibCheck: true,
|
|
458
|
-
outDir: "dist",
|
|
459
|
-
rootDir: ".",
|
|
460
|
-
declaration: true
|
|
461
|
-
},
|
|
462
|
-
include: ["*.ts", "src/**/*"],
|
|
463
|
-
exclude: ["dist", "node_modules"]
|
|
464
|
-
}, null, 2) + "\n",
|
|
465
|
-
"src/index.ts": (name) => `/**
|
|
466
|
-
* ${toTitleCase(name)} Plugin for ObjectStack
|
|
467
|
-
*
|
|
468
|
-
* Entry point \u2014 re-exports all plugin metadata.
|
|
469
|
-
*/
|
|
470
|
-
export * as objects from './objects';
|
|
471
|
-
`,
|
|
472
|
-
"src/objects/sample.ts": (name) => `import * as Data from '@objectstack/spec/data';
|
|
473
|
-
|
|
474
|
-
const sample: Data.Object = {
|
|
475
|
-
name: '${name}_sample',
|
|
476
|
-
label: '${toTitleCase(name)} Sample',
|
|
477
|
-
ownership: 'own',
|
|
478
|
-
fields: {
|
|
479
|
-
name: {
|
|
480
|
-
type: 'text',
|
|
481
|
-
label: 'Name',
|
|
482
|
-
required: true,
|
|
483
|
-
},
|
|
484
|
-
},
|
|
485
|
-
};
|
|
486
|
-
|
|
487
|
-
export default sample;
|
|
488
|
-
`,
|
|
489
|
-
"src/objects/index.ts": () => `export { default as sample } from './sample';
|
|
490
|
-
`,
|
|
491
|
-
"test/sample.test.ts": (name) => `import { describe, it, expect } from 'vitest';
|
|
492
|
-
import sample from '../src/objects/sample';
|
|
493
|
-
|
|
494
|
-
describe('${name} plugin', () => {
|
|
495
|
-
it('should export a valid sample object', () => {
|
|
496
|
-
expect(sample).toBeDefined();
|
|
497
|
-
expect(sample.name).toBe('${name}_sample');
|
|
498
|
-
expect(sample.fields).toHaveProperty('name');
|
|
499
|
-
});
|
|
500
|
-
});
|
|
501
|
-
`,
|
|
502
|
-
".gitignore": () => `node_modules/
|
|
503
|
-
dist/
|
|
504
|
-
*.tsbuildinfo
|
|
505
|
-
`,
|
|
506
|
-
"README.md": (name) => `# @objectstack/plugin-${name}
|
|
507
|
-
|
|
508
|
-
ObjectStack Plugin: ${toTitleCase(name)}
|
|
509
|
-
|
|
510
|
-
## Installation
|
|
511
|
-
|
|
512
|
-
\`\`\`bash
|
|
513
|
-
npm install @objectstack/plugin-${name}
|
|
514
|
-
\`\`\`
|
|
515
|
-
|
|
516
|
-
## Usage
|
|
517
|
-
|
|
518
|
-
\`\`\`typescript
|
|
519
|
-
import { defineStack } from '@objectstack/spec';
|
|
520
|
-
|
|
521
|
-
export default defineStack({
|
|
522
|
-
plugins: [
|
|
523
|
-
'@objectstack/plugin-${name}',
|
|
524
|
-
],
|
|
525
|
-
});
|
|
526
|
-
\`\`\`
|
|
527
|
-
|
|
528
|
-
## Development
|
|
529
|
-
|
|
530
|
-
\`\`\`bash
|
|
531
|
-
# Run tests
|
|
532
|
-
npm test
|
|
533
|
-
|
|
534
|
-
# Build
|
|
535
|
-
npm run build
|
|
536
|
-
|
|
537
|
-
# Validate metadata
|
|
538
|
-
npm run validate
|
|
539
|
-
\`\`\`
|
|
540
|
-
|
|
541
|
-
## License
|
|
542
|
-
|
|
543
|
-
MIT
|
|
544
|
-
`
|
|
545
|
-
}
|
|
41
|
+
procurement: {
|
|
42
|
+
description: "Source-to-pay \u2014 vendors, POs, receipts, invoice matching",
|
|
43
|
+
source: { kind: "remote", pkg: "procurement" }
|
|
546
44
|
}
|
|
547
45
|
};
|
|
548
|
-
function readTemplate(filename) {
|
|
549
|
-
return fs.readFileSync(path.join(TEMPLATES_DIR, filename), "utf-8");
|
|
550
|
-
}
|
|
551
|
-
var AI_CONFIG_FILES = {
|
|
552
|
-
".github/copilot-instructions.md": (name) => readTemplate("copilot-instructions.md").replaceAll("{{PROJECT_NAME}}", name).replaceAll("{{PROJECT_TITLE}}", toTitleCase(name))
|
|
553
|
-
};
|
|
554
46
|
function toTitleCase(str) {
|
|
555
47
|
return str.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
556
48
|
}
|
|
@@ -574,16 +66,132 @@ function printStep(msg) {
|
|
|
574
66
|
function printWarning(msg) {
|
|
575
67
|
console.log(chalk.yellow(` \u26A0 ${msg}`));
|
|
576
68
|
}
|
|
577
|
-
|
|
69
|
+
function detectPackageManager() {
|
|
70
|
+
try {
|
|
71
|
+
execSync("pnpm --version", { stdio: "ignore" });
|
|
72
|
+
return "pnpm";
|
|
73
|
+
} catch {
|
|
74
|
+
return "npm";
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function copyDir(src, dest, collected, rel = "") {
|
|
78
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
79
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
80
|
+
const srcPath = path.join(src, entry.name);
|
|
81
|
+
const destPath = path.join(dest, entry.name);
|
|
82
|
+
const relPath = rel ? `${rel}/${entry.name}` : entry.name;
|
|
83
|
+
if (entry.isDirectory()) {
|
|
84
|
+
copyDir(srcPath, destPath, collected, relPath);
|
|
85
|
+
} else if (entry.isFile()) {
|
|
86
|
+
fs.copyFileSync(srcPath, destPath);
|
|
87
|
+
collected.push(relPath);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function loadBundled(templateDir, targetDir) {
|
|
92
|
+
const src = path.join(BUNDLED_TEMPLATES_DIR, templateDir);
|
|
93
|
+
if (!fs.existsSync(src)) {
|
|
94
|
+
throw new Error(`Bundled template missing on disk: ${src}`);
|
|
95
|
+
}
|
|
96
|
+
const collected = [];
|
|
97
|
+
copyDir(src, targetDir, collected);
|
|
98
|
+
return collected;
|
|
99
|
+
}
|
|
100
|
+
async function downloadTarball(url, destFile) {
|
|
101
|
+
const res = await fetch(url, { redirect: "follow" });
|
|
102
|
+
if (!res.ok || !res.body) {
|
|
103
|
+
throw new Error(`Download failed: ${url} (${res.status})`);
|
|
104
|
+
}
|
|
105
|
+
const out = createWriteStream(destFile);
|
|
106
|
+
for await (const chunk of res.body) {
|
|
107
|
+
out.write(chunk);
|
|
108
|
+
}
|
|
109
|
+
await new Promise((resolve, reject) => {
|
|
110
|
+
out.end((err) => err ? reject(err) : resolve());
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
async function loadRemote(pkgName, targetDir) {
|
|
114
|
+
const tmp = await mkdtemp(path.join(os.tmpdir(), "create-objectstack-"));
|
|
115
|
+
try {
|
|
116
|
+
const tarball = path.join(tmp, "templates.tar.gz");
|
|
117
|
+
printStep(`Fetching template "${pkgName}" from ${REMOTE_REPO}@${REMOTE_BRANCH}\u2026`);
|
|
118
|
+
await downloadTarball(REMOTE_TARBALL_URL, tarball);
|
|
119
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
120
|
+
const collected = [];
|
|
121
|
+
await pipeline(
|
|
122
|
+
createReadStream(tarball),
|
|
123
|
+
createGunzip(),
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
125
|
+
tar.extract({
|
|
126
|
+
cwd: targetDir,
|
|
127
|
+
strip: 3,
|
|
128
|
+
filter: (p) => {
|
|
129
|
+
const parts = p.split("/");
|
|
130
|
+
return parts[1] === "packages" && parts[2] === pkgName && parts.length > 3;
|
|
131
|
+
},
|
|
132
|
+
onentry: (entry) => {
|
|
133
|
+
if (entry.type === "File") {
|
|
134
|
+
const parts = entry.path.split("/").slice(3);
|
|
135
|
+
if (parts.length > 0) collected.push(parts.join("/"));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
);
|
|
140
|
+
if (collected.length === 0) {
|
|
141
|
+
throw new Error(
|
|
142
|
+
`Template "${pkgName}" not found in ${REMOTE_REPO}@${REMOTE_BRANCH} (expected packages/${pkgName}/).`
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
return collected;
|
|
146
|
+
} finally {
|
|
147
|
+
await rm(tmp, { recursive: true, force: true });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function rewriteProjectIdentity(targetDir, projectName) {
|
|
151
|
+
const title = toTitleCase(projectName);
|
|
152
|
+
const pkgPath = path.join(targetDir, "package.json");
|
|
153
|
+
if (fs.existsSync(pkgPath)) {
|
|
154
|
+
try {
|
|
155
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
156
|
+
pkg.name = projectName;
|
|
157
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
158
|
+
} catch {
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const manifestPath = path.join(targetDir, "objectstack.manifest.json");
|
|
162
|
+
if (fs.existsSync(manifestPath)) {
|
|
163
|
+
try {
|
|
164
|
+
const m = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
165
|
+
m.name = projectName;
|
|
166
|
+
m.displayName = title;
|
|
167
|
+
fs.writeFileSync(manifestPath, JSON.stringify(m, null, 2) + "\n");
|
|
168
|
+
} catch {
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const configPath = path.join(targetDir, "objectstack.config.ts");
|
|
172
|
+
if (fs.existsSync(configPath)) {
|
|
173
|
+
let cfg = fs.readFileSync(configPath, "utf8");
|
|
174
|
+
cfg = cfg.replace(/(\bid:\s*)(['"`])[^'"`]*\2/, `$1$2${projectName}$2`);
|
|
175
|
+
cfg = cfg.replace(/(\bname:\s*)(['"`])[^'"`]*\2/, `$1$2${title}$2`);
|
|
176
|
+
fs.writeFileSync(configPath, cfg);
|
|
177
|
+
}
|
|
178
|
+
const readmePath = path.join(targetDir, "README.md");
|
|
179
|
+
if (fs.existsSync(readmePath)) {
|
|
180
|
+
let md = fs.readFileSync(readmePath, "utf8");
|
|
181
|
+
md = md.replace(/^#\s+.*$/m, `# ${title}`);
|
|
182
|
+
fs.writeFileSync(readmePath, md);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
var program = new Command().name("create-objectstack").description("Create a new ObjectStack environment").version("6.2.0").argument("[name]", "Environment name (defaults to current directory name)").option(
|
|
578
186
|
"-t, --template <template>",
|
|
579
|
-
|
|
580
|
-
"
|
|
581
|
-
).option("--skip-install", "Skip dependency installation").action(async (name, options) => {
|
|
187
|
+
`Template: ${Object.keys(TEMPLATES).join(", ")}`,
|
|
188
|
+
"blank"
|
|
189
|
+
).option("--skip-install", "Skip dependency installation").option("--skip-skills", "Skip installing ObjectStack AI skills").action(async (name, options) => {
|
|
582
190
|
console.log("");
|
|
583
191
|
console.log(chalk.bold.cyan(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
584
|
-
console.log(chalk.bold.cyan(" \u2551") + chalk.bold(" \u25C6 Create ObjectStack ") + chalk.dim("
|
|
192
|
+
console.log(chalk.bold.cyan(" \u2551") + chalk.bold(" \u25C6 Create ObjectStack ") + chalk.dim("v6.x") + chalk.bold.cyan(" \u2551"));
|
|
585
193
|
console.log(chalk.bold.cyan(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
|
|
586
|
-
printHeader("New
|
|
194
|
+
printHeader("New Environment");
|
|
587
195
|
const template = TEMPLATES[options.template];
|
|
588
196
|
if (!template) {
|
|
589
197
|
printError(`Unknown template: ${options.template}`);
|
|
@@ -594,7 +202,7 @@ var program = new Command().name("create-objectstack").description("Create a new
|
|
|
594
202
|
const projectName = name || path.basename(cwd);
|
|
595
203
|
const targetDir = name ? path.resolve(cwd, name) : cwd;
|
|
596
204
|
const isCurrentDir = targetDir === cwd;
|
|
597
|
-
printKV("
|
|
205
|
+
printKV("Environment", projectName);
|
|
598
206
|
printKV("Template", `${options.template} \u2014 ${template.description}`);
|
|
599
207
|
printKV("Directory", targetDir);
|
|
600
208
|
console.log("");
|
|
@@ -605,25 +213,22 @@ var program = new Command().name("create-objectstack").description("Create a new
|
|
|
605
213
|
process.exit(1);
|
|
606
214
|
}
|
|
607
215
|
}
|
|
608
|
-
const createdFiles = [];
|
|
609
216
|
try {
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
const dir = path.dirname(fullPath);
|
|
617
|
-
if (!fs.existsSync(dir)) {
|
|
618
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
619
|
-
}
|
|
620
|
-
fs.writeFileSync(fullPath, contentFn(projectName));
|
|
621
|
-
createdFiles.push(filePath);
|
|
217
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
218
|
+
let createdFiles;
|
|
219
|
+
if (template.source.kind === "bundled") {
|
|
220
|
+
createdFiles = loadBundled(template.source.dir, targetDir);
|
|
221
|
+
} else {
|
|
222
|
+
createdFiles = await loadRemote(template.source.pkg, targetDir);
|
|
622
223
|
}
|
|
224
|
+
rewriteProjectIdentity(targetDir, projectName);
|
|
623
225
|
console.log(chalk.bold(" Created files:"));
|
|
624
|
-
for (const f of createdFiles) {
|
|
226
|
+
for (const f of createdFiles.slice(0, 20)) {
|
|
625
227
|
console.log(chalk.green(` + ${f}`));
|
|
626
228
|
}
|
|
229
|
+
if (createdFiles.length > 20) {
|
|
230
|
+
console.log(chalk.dim(` \u2026 and ${createdFiles.length - 20} more`));
|
|
231
|
+
}
|
|
627
232
|
console.log("");
|
|
628
233
|
if (!options.skipInstall) {
|
|
629
234
|
printStep("Installing dependencies...");
|
|
@@ -636,7 +241,7 @@ var program = new Command().name("create-objectstack").description("Create a new
|
|
|
636
241
|
console.log("");
|
|
637
242
|
}
|
|
638
243
|
}
|
|
639
|
-
if (!options.skipInstall) {
|
|
244
|
+
if (!options.skipInstall && !options.skipSkills) {
|
|
640
245
|
printStep("Installing AI skills for your coding agent...");
|
|
641
246
|
try {
|
|
642
247
|
execSync("npx -y skills add objectstack-ai/framework --all", {
|
|
@@ -651,7 +256,7 @@ var program = new Command().name("create-objectstack").description("Create a new
|
|
|
651
256
|
console.log("");
|
|
652
257
|
}
|
|
653
258
|
}
|
|
654
|
-
printSuccess("
|
|
259
|
+
printSuccess("Environment created!");
|
|
655
260
|
console.log("");
|
|
656
261
|
console.log(chalk.bold(" Next steps:"));
|
|
657
262
|
if (!isCurrentDir) {
|
|
@@ -662,23 +267,16 @@ var program = new Command().name("create-objectstack").description("Create a new
|
|
|
662
267
|
}
|
|
663
268
|
console.log(chalk.dim(" npm run dev # Start development server"));
|
|
664
269
|
console.log(chalk.dim(" npm run validate # Check configuration"));
|
|
665
|
-
if (options.skipInstall) {
|
|
270
|
+
if (options.skipInstall || options.skipSkills) {
|
|
666
271
|
console.log("");
|
|
667
272
|
console.log(chalk.bold(" AI Skills (recommended):"));
|
|
668
273
|
console.log(chalk.dim(" npx skills add objectstack-ai/framework"));
|
|
669
274
|
}
|
|
670
275
|
console.log("");
|
|
671
276
|
} catch (error) {
|
|
672
|
-
|
|
277
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
278
|
+
printError(msg);
|
|
673
279
|
process.exit(1);
|
|
674
280
|
}
|
|
675
281
|
});
|
|
676
|
-
function detectPackageManager() {
|
|
677
|
-
try {
|
|
678
|
-
execSync("pnpm --version", { stdio: "ignore" });
|
|
679
|
-
return "pnpm";
|
|
680
|
-
} catch {
|
|
681
|
-
return "npm";
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
282
|
program.parse();
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Blank Starter
|
|
2
|
+
|
|
3
|
+
Minimal ObjectStack environment — a clean slate for building.
|
|
4
|
+
|
|
5
|
+
## Getting started
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm install
|
|
9
|
+
pnpm dev
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The REST API is served at `http://localhost:3000/api`.
|
|
13
|
+
|
|
14
|
+
## Layout
|
|
15
|
+
|
|
16
|
+
- `objectstack.config.ts` — environment manifest (objects, API, plugins)
|
|
17
|
+
- `src/objects/` — object definitions (one file per object)
|
|
18
|
+
|
|
19
|
+
## Next steps
|
|
20
|
+
|
|
21
|
+
- Add an object: see the `objectstack-data` skill.
|
|
22
|
+
- Add a view or app: see `objectstack-ui`.
|
|
23
|
+
- Add a flow or automation: see `objectstack-automation`.
|
|
24
|
+
- Add an AI agent: see `objectstack-ai`.
|
|
25
|
+
|
|
26
|
+
Skills live in `skills/` in the ObjectStack framework repo and in the in-IDE
|
|
27
|
+
assistant catalog.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineStack } from '@objectstack/spec';
|
|
2
|
+
import * as objects from './src/objects/index.js';
|
|
3
|
+
|
|
4
|
+
export default defineStack({
|
|
5
|
+
manifest: {
|
|
6
|
+
id: 'blank',
|
|
7
|
+
version: '0.1.0',
|
|
8
|
+
type: 'app',
|
|
9
|
+
name: 'Blank Starter',
|
|
10
|
+
description: 'Minimal ObjectStack environment — a clean slate for building.',
|
|
11
|
+
},
|
|
12
|
+
objects: Object.values(objects),
|
|
13
|
+
api: {
|
|
14
|
+
rest: {
|
|
15
|
+
enabled: true,
|
|
16
|
+
basePath: '/api',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://schemas.objectstack.dev/template-manifest.json",
|
|
3
|
+
"name": "blank",
|
|
4
|
+
"specVersion": "^6.0.0",
|
|
5
|
+
"displayName": "Blank Starter",
|
|
6
|
+
"description": "Minimal ObjectStack environment with a single object — a clean slate for building.",
|
|
7
|
+
"category": "starter",
|
|
8
|
+
"isStarter": true,
|
|
9
|
+
"skills": ["objectstack-platform", "objectstack-data"],
|
|
10
|
+
"readmePath": "README.md",
|
|
11
|
+
"scaffold": {
|
|
12
|
+
"variables": {
|
|
13
|
+
"appName": { "type": "string", "prompt": "Application name", "default": "my-app" }
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "objectstack-blank",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "objectstack serve --watch",
|
|
8
|
+
"start": "objectstack serve",
|
|
9
|
+
"build": "objectstack build",
|
|
10
|
+
"validate": "objectstack validate",
|
|
11
|
+
"typecheck": "tsc --noEmit"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@objectstack/spec": "^6.0.0",
|
|
15
|
+
"@objectstack/runtime": "^6.0.0",
|
|
16
|
+
"@objectstack/driver-memory": "^6.0.0",
|
|
17
|
+
"@objectstack/plugin-hono-server": "^6.0.0"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@objectstack/cli": "^6.0.0",
|
|
21
|
+
"typescript": "^5.3.0"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Note } from './note.object.js';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
|
|
3
|
+
import { ObjectSchema, Field } from '@objectstack/spec/data';
|
|
4
|
+
|
|
5
|
+
export const Note = ObjectSchema.create({
|
|
6
|
+
name: 'note',
|
|
7
|
+
label: 'Note',
|
|
8
|
+
pluralLabel: 'Notes',
|
|
9
|
+
icon: 'sticky-note',
|
|
10
|
+
description: 'A short note — the starter object for a blank environment.',
|
|
11
|
+
|
|
12
|
+
fields: {
|
|
13
|
+
title: Field.text({
|
|
14
|
+
label: 'Title',
|
|
15
|
+
required: true,
|
|
16
|
+
searchable: true,
|
|
17
|
+
maxLength: 200,
|
|
18
|
+
}),
|
|
19
|
+
body: Field.longText({
|
|
20
|
+
label: 'Body',
|
|
21
|
+
}),
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
enable: {
|
|
25
|
+
apiEnabled: true,
|
|
26
|
+
searchable: true,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"resolveJsonModule": true,
|
|
10
|
+
"allowImportingTsExtensions": false,
|
|
11
|
+
"noEmit": true,
|
|
12
|
+
"isolatedModules": true
|
|
13
|
+
},
|
|
14
|
+
"include": ["objectstack.config.ts", "src/**/*"]
|
|
15
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-objectstack",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.3.0",
|
|
4
4
|
"description": "Create a new ObjectStack project — npx create-objectstack",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-objectstack": "./bin/create-objectstack.js"
|
|
@@ -16,10 +16,12 @@
|
|
|
16
16
|
"license": "Apache-2.0",
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"chalk": "^5.6.2",
|
|
19
|
-
"commander": "^14.0.3"
|
|
19
|
+
"commander": "^14.0.3",
|
|
20
|
+
"tar": "^7.4.3"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
23
|
"@types/node": "^25.9.1",
|
|
24
|
+
"@types/tar": "^6.1.13",
|
|
23
25
|
"tsup": "^8.5.1",
|
|
24
26
|
"typescript": "^6.0.3"
|
|
25
27
|
},
|