swallowkit 1.0.0-beta.7 → 1.0.0-beta.9
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 +56 -0
- package/dist/cli/commands/dev-seeds.d.ts +35 -0
- package/dist/cli/commands/dev-seeds.d.ts.map +1 -0
- package/dist/cli/commands/dev-seeds.js +292 -0
- package/dist/cli/commands/dev-seeds.js.map +1 -0
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +57 -53
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +3 -1
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +27 -20
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/index.js +2 -1
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/dev-seeds.test.ts +112 -0
- package/src/__tests__/init.test.ts +21 -0
- package/src/cli/commands/dev-seeds.ts +358 -0
- package/src/cli/commands/dev.ts +68 -57
- package/src/cli/commands/index.ts +1 -0
- package/src/cli/commands/init.ts +27 -20
- package/src/cli/index.ts +3 -2
package/README.md
CHANGED
|
@@ -139,6 +139,62 @@ pnpm dlx swallowkit dev
|
|
|
139
139
|
- Next.js: http://localhost:3000
|
|
140
140
|
- Azure Functions: http://localhost:7071
|
|
141
141
|
|
|
142
|
+
If you want to replace Cosmos DB Emulator data before startup, generate an environment template and then launch `dev` with that environment:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
npx swallowkit create-dev-seeds local
|
|
146
|
+
# edit dev-seeds/local/*.json
|
|
147
|
+
npx swallowkit dev --seed-env local
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
This workflow is designed for local debugging against the Cosmos DB Emulator:
|
|
151
|
+
|
|
152
|
+
- `create-dev-seeds <environment>` generates one JSON template per schema under `dev-seeds/<environment>/`
|
|
153
|
+
- each file name maps to a schema/container, for example `shared/models/todo.ts` -> `dev-seeds/local/todo.json` -> `Todos`
|
|
154
|
+
- when you start `dev --seed-env <environment>`, SwallowKit replaces the existing data for each matching container with the JSON documents from that environment
|
|
155
|
+
- containers without a matching JSON file are left untouched
|
|
156
|
+
- if `--seed-env` is omitted, or `dev-seeds/<environment>/` does not exist, current emulator data is preserved
|
|
157
|
+
|
|
158
|
+
Example file layout:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
dev-seeds/
|
|
162
|
+
local/
|
|
163
|
+
todo.json
|
|
164
|
+
category.json
|
|
165
|
+
staging-debug/
|
|
166
|
+
todo.json
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Each `{schema}.json` file can contain either a single JSON object or an array of JSON objects. Every document must include an `id`:
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
[
|
|
173
|
+
{
|
|
174
|
+
"id": "seed-todo-001",
|
|
175
|
+
"name": "Seed todo one",
|
|
176
|
+
"createdAt": "2026-03-21T00:00:00.000Z",
|
|
177
|
+
"updatedAt": "2026-03-21T00:00:00.000Z"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"id": "seed-todo-002",
|
|
181
|
+
"name": "Seed todo two",
|
|
182
|
+
"createdAt": "2026-03-21T00:00:01.000Z",
|
|
183
|
+
"updatedAt": "2026-03-21T00:00:01.000Z"
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Recommended workflow:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
npx swallowkit create-model todo
|
|
192
|
+
npx swallowkit scaffold shared/models/todo.ts
|
|
193
|
+
npx swallowkit create-dev-seeds local
|
|
194
|
+
# edit dev-seeds/local/todo.json
|
|
195
|
+
npx swallowkit dev --seed-env local
|
|
196
|
+
```
|
|
197
|
+
|
|
142
198
|
### 5. Use from Frontend
|
|
143
199
|
|
|
144
200
|
```typescript
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { CosmosClient } from "@azure/cosmos";
|
|
3
|
+
import { ModelInfo } from "../../core/scaffold/model-parser";
|
|
4
|
+
export type SeedDocument = Record<string, unknown>;
|
|
5
|
+
interface GenerateDevSeedTemplatesOptions {
|
|
6
|
+
environment: string;
|
|
7
|
+
modelsDir?: string;
|
|
8
|
+
seedsDir?: string;
|
|
9
|
+
force?: boolean;
|
|
10
|
+
}
|
|
11
|
+
interface ApplyDevSeedEnvironmentOptions {
|
|
12
|
+
client: CosmosClient;
|
|
13
|
+
databaseName: string;
|
|
14
|
+
environment: string;
|
|
15
|
+
models: ModelInfo[];
|
|
16
|
+
seedsDir?: string;
|
|
17
|
+
}
|
|
18
|
+
interface LoadedSeedFile {
|
|
19
|
+
model: ModelInfo;
|
|
20
|
+
containerName: string;
|
|
21
|
+
documents: SeedDocument[];
|
|
22
|
+
filePath: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function getContainerNameForModel(model: Pick<ModelInfo, "name">): string;
|
|
25
|
+
export declare function getSeedEnvironmentDir(environment: string, seedsDir?: string): string;
|
|
26
|
+
export declare function normalizeSeedIdentifier(value: string): string;
|
|
27
|
+
export declare function parseSeedDocuments(content: string, filePath: string): SeedDocument[];
|
|
28
|
+
export declare function loadProjectModels(modelsDir?: string): Promise<ModelInfo[]>;
|
|
29
|
+
export declare function buildSeedTemplateDocument(model: ModelInfo, allModels?: ModelInfo[], seenModels?: Set<string>): SeedDocument;
|
|
30
|
+
export declare function loadDevSeedFiles(environment: string, models: ModelInfo[], seedsDir?: string): Promise<LoadedSeedFile[]>;
|
|
31
|
+
export declare function applyDevSeedEnvironment({ client, databaseName, environment, models, seedsDir, }: ApplyDevSeedEnvironmentOptions): Promise<boolean>;
|
|
32
|
+
export declare function generateDevSeedTemplates({ environment, modelsDir, seedsDir, force, }: GenerateDevSeedTemplatesOptions): Promise<void>;
|
|
33
|
+
export declare const devSeedsCommand: Command;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=dev-seeds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-seeds.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/dev-seeds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAA8B,MAAM,eAAe,CAAC;AAIzE,OAAO,EAAa,SAAS,EAA6B,MAAM,kCAAkC,CAAC;AAEnG,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnD,UAAU,+BAA+B;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,UAAU,8BAA8B;IACtC,MAAM,EAAE,YAAY,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,cAAc;IACtB,KAAK,EAAE,SAAS,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,MAAM,CAE/E;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAoB,GAAG,MAAM,CAEjG;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAkBpF;AAED,wBAAsB,iBAAiB,CAAC,SAAS,GAAE,MAAwB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAEjG;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,EAChB,SAAS,GAAE,SAAS,EAAY,EAChC,UAAU,GAAE,GAAG,CAAC,MAAM,CAAa,GAClC,YAAY,CAGd;AAED,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,SAAS,EAAE,EACnB,QAAQ,GAAE,MAAoB,GAC7B,OAAO,CAAC,cAAc,EAAE,CAAC,CAgC3B;AAED,wBAAsB,uBAAuB,CAAC,EAC5C,MAAM,EACN,YAAY,EACZ,WAAW,EACX,MAAM,EACN,QAAsB,GACvB,EAAE,8BAA8B,GAAG,OAAO,CAAC,OAAO,CAAC,CA+BnD;AAED,wBAAsB,wBAAwB,CAAC,EAC7C,WAAW,EACX,SAA2B,EAC3B,QAAsB,EACtB,KAAa,GACd,EAAE,+BAA+B,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCjD;AAED,eAAO,MAAM,eAAe,SAcxB,CAAC"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.devSeedsCommand = void 0;
|
|
37
|
+
exports.getContainerNameForModel = getContainerNameForModel;
|
|
38
|
+
exports.getSeedEnvironmentDir = getSeedEnvironmentDir;
|
|
39
|
+
exports.normalizeSeedIdentifier = normalizeSeedIdentifier;
|
|
40
|
+
exports.parseSeedDocuments = parseSeedDocuments;
|
|
41
|
+
exports.loadProjectModels = loadProjectModels;
|
|
42
|
+
exports.buildSeedTemplateDocument = buildSeedTemplateDocument;
|
|
43
|
+
exports.loadDevSeedFiles = loadDevSeedFiles;
|
|
44
|
+
exports.applyDevSeedEnvironment = applyDevSeedEnvironment;
|
|
45
|
+
exports.generateDevSeedTemplates = generateDevSeedTemplates;
|
|
46
|
+
const commander_1 = require("commander");
|
|
47
|
+
const cosmos_1 = require("@azure/cosmos");
|
|
48
|
+
const fs = __importStar(require("fs"));
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
const config_1 = require("../../core/config");
|
|
51
|
+
const model_parser_1 = require("../../core/scaffold/model-parser");
|
|
52
|
+
function getContainerNameForModel(model) {
|
|
53
|
+
return `${model.name}s`;
|
|
54
|
+
}
|
|
55
|
+
function getSeedEnvironmentDir(environment, seedsDir = "dev-seeds") {
|
|
56
|
+
return path.join(process.cwd(), seedsDir, environment);
|
|
57
|
+
}
|
|
58
|
+
function normalizeSeedIdentifier(value) {
|
|
59
|
+
return value.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
60
|
+
}
|
|
61
|
+
function parseSeedDocuments(content, filePath) {
|
|
62
|
+
const parsed = JSON.parse(content);
|
|
63
|
+
if (Array.isArray(parsed)) {
|
|
64
|
+
return parsed.map((item, index) => {
|
|
65
|
+
if (!isSeedDocument(item)) {
|
|
66
|
+
throw new Error(`${filePath} must contain only JSON objects. Invalid item at index ${index}.`);
|
|
67
|
+
}
|
|
68
|
+
return item;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
if (isSeedDocument(parsed)) {
|
|
72
|
+
return [parsed];
|
|
73
|
+
}
|
|
74
|
+
throw new Error(`${filePath} must contain a JSON object or an array of JSON objects.`);
|
|
75
|
+
}
|
|
76
|
+
async function loadProjectModels(modelsDir = "shared/models") {
|
|
77
|
+
return (0, model_parser_1.getAllModels)(modelsDir);
|
|
78
|
+
}
|
|
79
|
+
function buildSeedTemplateDocument(model, allModels = [model], seenModels = new Set()) {
|
|
80
|
+
const modelLookup = new Map(allModels.map((candidate) => [candidate.name, candidate]));
|
|
81
|
+
return buildSeedTemplateDocumentInternal(model, modelLookup, seenModels);
|
|
82
|
+
}
|
|
83
|
+
async function loadDevSeedFiles(environment, models, seedsDir = "dev-seeds") {
|
|
84
|
+
const environmentDir = getSeedEnvironmentDir(environment, seedsDir);
|
|
85
|
+
if (!fs.existsSync(environmentDir)) {
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
const modelAliases = buildModelAliasMap(models);
|
|
89
|
+
const seedFiles = fs.readdirSync(environmentDir).filter((entry) => entry.endsWith(".json"));
|
|
90
|
+
const loaded = [];
|
|
91
|
+
for (const fileName of seedFiles) {
|
|
92
|
+
const filePath = path.join(environmentDir, fileName);
|
|
93
|
+
const fileStem = path.basename(fileName, ".json");
|
|
94
|
+
const model = modelAliases.get(normalizeSeedIdentifier(fileStem));
|
|
95
|
+
if (!model) {
|
|
96
|
+
console.warn(`⚠️ Skipping seed file without matching schema: ${filePath}`);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const documents = parseSeedDocuments(fs.readFileSync(filePath, "utf-8"), filePath);
|
|
100
|
+
validateSeedDocuments(documents, filePath);
|
|
101
|
+
loaded.push({
|
|
102
|
+
model,
|
|
103
|
+
containerName: getContainerNameForModel(model),
|
|
104
|
+
documents,
|
|
105
|
+
filePath,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return loaded;
|
|
109
|
+
}
|
|
110
|
+
async function applyDevSeedEnvironment({ client, databaseName, environment, models, seedsDir = "dev-seeds", }) {
|
|
111
|
+
const environmentDir = getSeedEnvironmentDir(environment, seedsDir);
|
|
112
|
+
if (!fs.existsSync(environmentDir)) {
|
|
113
|
+
console.log(`ℹ️ Seed environment "${environment}" not found at ${environmentDir}. Keeping existing Cosmos DB data.`);
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
const seedFiles = await loadDevSeedFiles(environment, models, seedsDir);
|
|
117
|
+
if (seedFiles.length === 0) {
|
|
118
|
+
console.log(`ℹ️ No seed files found for environment "${environment}". Keeping existing Cosmos DB data.`);
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
const database = client.database(databaseName);
|
|
122
|
+
console.log(`🧪 Applying Cosmos DB seed data for environment "${environment}"...`);
|
|
123
|
+
for (const seedFile of seedFiles) {
|
|
124
|
+
await recreateContainer(database, seedFile.containerName);
|
|
125
|
+
const container = database.container(seedFile.containerName);
|
|
126
|
+
for (const document of seedFile.documents) {
|
|
127
|
+
await container.items.create(document);
|
|
128
|
+
}
|
|
129
|
+
console.log(`✅ Seeded "${seedFile.containerName}" with ${seedFile.documents.length} item(s) from ${path.basename(seedFile.filePath)}`);
|
|
130
|
+
}
|
|
131
|
+
console.log("✅ Cosmos DB seed replacement complete\n");
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
async function generateDevSeedTemplates({ environment, modelsDir = "shared/models", seedsDir = "dev-seeds", force = false, }) {
|
|
135
|
+
(0, config_1.ensureSwallowKitProject)("create-dev-seeds");
|
|
136
|
+
console.log(`🧪 Generating dev seed templates for environment "${environment}"...\n`);
|
|
137
|
+
const models = await loadProjectModels(modelsDir);
|
|
138
|
+
if (models.length === 0) {
|
|
139
|
+
console.log("⚠️ No schemas found under shared/models. Nothing was generated.");
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const environmentDir = getSeedEnvironmentDir(environment, seedsDir);
|
|
143
|
+
fs.mkdirSync(environmentDir, { recursive: true });
|
|
144
|
+
const writtenFiles = [];
|
|
145
|
+
const skippedFiles = [];
|
|
146
|
+
for (const model of models) {
|
|
147
|
+
const filePath = path.join(environmentDir, `${(0, model_parser_1.toKebabCase)(model.name)}.json`);
|
|
148
|
+
if (!force && fs.existsSync(filePath)) {
|
|
149
|
+
skippedFiles.push(filePath);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const content = JSON.stringify([buildSeedTemplateDocument(model, models)], null, 2) + "\n";
|
|
153
|
+
fs.writeFileSync(filePath, content, "utf-8");
|
|
154
|
+
writtenFiles.push(filePath);
|
|
155
|
+
console.log(`✅ Created: ${filePath}`);
|
|
156
|
+
}
|
|
157
|
+
if (skippedFiles.length > 0) {
|
|
158
|
+
console.log("");
|
|
159
|
+
console.log(`⏭️ Skipped ${skippedFiles.length} existing file(s). Use --force to overwrite them.`);
|
|
160
|
+
}
|
|
161
|
+
console.log("");
|
|
162
|
+
console.log("📝 Next steps:");
|
|
163
|
+
console.log(` 1. Edit JSON files under ${environmentDir}`);
|
|
164
|
+
console.log(` 2. Run 'swallowkit dev --seed-env ${environment}' to replace emulator data before startup`);
|
|
165
|
+
}
|
|
166
|
+
exports.devSeedsCommand = new commander_1.Command()
|
|
167
|
+
.name("create-dev-seeds")
|
|
168
|
+
.description("Generate dev seed JSON templates under dev-seeds/<environment> from shared/models schemas")
|
|
169
|
+
.argument("<environment>", "Seed environment name")
|
|
170
|
+
.option("--models-dir <dir>", "Models directory", "shared/models")
|
|
171
|
+
.option("--seeds-dir <dir>", "Dev seeds directory", "dev-seeds")
|
|
172
|
+
.option("--force", "Overwrite existing seed JSON files", false)
|
|
173
|
+
.action(async (environment, options) => {
|
|
174
|
+
await generateDevSeedTemplates({
|
|
175
|
+
environment,
|
|
176
|
+
modelsDir: options.modelsDir,
|
|
177
|
+
seedsDir: options.seedsDir,
|
|
178
|
+
force: options.force,
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
function buildSeedTemplateDocumentInternal(model, modelLookup, seenModels) {
|
|
182
|
+
const nextSeen = new Set(seenModels);
|
|
183
|
+
nextSeen.add(model.name);
|
|
184
|
+
const document = {};
|
|
185
|
+
for (const field of model.fields) {
|
|
186
|
+
document[field.name] = buildTemplateValueForField(model, field, modelLookup, nextSeen);
|
|
187
|
+
}
|
|
188
|
+
return document;
|
|
189
|
+
}
|
|
190
|
+
function buildTemplateValueForField(model, field, modelLookup, seenModels) {
|
|
191
|
+
if (field.isNestedSchema && field.nestedModelName) {
|
|
192
|
+
const nestedModel = modelLookup.get(field.nestedModelName);
|
|
193
|
+
if (nestedModel) {
|
|
194
|
+
if (seenModels.has(nestedModel.name)) {
|
|
195
|
+
const fallback = { id: `${(0, model_parser_1.toKebabCase)(nestedModel.name)}-001` };
|
|
196
|
+
return field.isArray ? [fallback] : fallback;
|
|
197
|
+
}
|
|
198
|
+
const nestedDocument = buildSeedTemplateDocumentInternal(nestedModel, modelLookup, seenModels);
|
|
199
|
+
return field.isArray ? [nestedDocument] : nestedDocument;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (field.isArray) {
|
|
203
|
+
return [buildScalarTemplateValue(model, field)];
|
|
204
|
+
}
|
|
205
|
+
return buildScalarTemplateValue(model, field);
|
|
206
|
+
}
|
|
207
|
+
function buildScalarTemplateValue(model, field) {
|
|
208
|
+
if (field.name === "id") {
|
|
209
|
+
return `${(0, model_parser_1.toKebabCase)(model.name)}-001`;
|
|
210
|
+
}
|
|
211
|
+
if (field.enumValues && field.enumValues.length > 0) {
|
|
212
|
+
return field.enumValues[0];
|
|
213
|
+
}
|
|
214
|
+
if (field.type === "number") {
|
|
215
|
+
return 0;
|
|
216
|
+
}
|
|
217
|
+
if (field.type === "boolean") {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
if (field.type === "date" || field.name.endsWith("At")) {
|
|
221
|
+
return "2026-01-01T00:00:00.000Z";
|
|
222
|
+
}
|
|
223
|
+
if (field.type === "object") {
|
|
224
|
+
return {};
|
|
225
|
+
}
|
|
226
|
+
return `${(0, model_parser_1.toKebabCase)(model.name)}-${(0, model_parser_1.toKebabCase)(field.name)}-sample`;
|
|
227
|
+
}
|
|
228
|
+
function buildModelAliasMap(models) {
|
|
229
|
+
const aliases = new Map();
|
|
230
|
+
for (const model of models) {
|
|
231
|
+
const candidates = [
|
|
232
|
+
model.name,
|
|
233
|
+
model.schemaName,
|
|
234
|
+
(0, model_parser_1.toKebabCase)(model.name),
|
|
235
|
+
path.basename(model.filePath, path.extname(model.filePath)),
|
|
236
|
+
];
|
|
237
|
+
for (const candidate of candidates) {
|
|
238
|
+
const normalized = normalizeSeedIdentifier(candidate);
|
|
239
|
+
if (!aliases.has(normalized)) {
|
|
240
|
+
aliases.set(normalized, model);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return aliases;
|
|
245
|
+
}
|
|
246
|
+
function isSeedDocument(value) {
|
|
247
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
248
|
+
}
|
|
249
|
+
function validateSeedDocuments(documents, filePath) {
|
|
250
|
+
const ids = new Set();
|
|
251
|
+
documents.forEach((document, index) => {
|
|
252
|
+
if (typeof document.id !== "string" || document.id.trim().length === 0) {
|
|
253
|
+
throw new Error(`${filePath} item at index ${index} must contain a non-empty string id.`);
|
|
254
|
+
}
|
|
255
|
+
if (ids.has(document.id)) {
|
|
256
|
+
throw new Error(`${filePath} contains duplicate id "${document.id}".`);
|
|
257
|
+
}
|
|
258
|
+
ids.add(document.id);
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
async function recreateContainer(database, containerName) {
|
|
262
|
+
try {
|
|
263
|
+
await database.container(containerName).delete();
|
|
264
|
+
}
|
|
265
|
+
catch (error) {
|
|
266
|
+
if (error?.code !== 404) {
|
|
267
|
+
throw error;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
try {
|
|
271
|
+
await database.containers.createIfNotExists({
|
|
272
|
+
id: containerName,
|
|
273
|
+
partitionKey: {
|
|
274
|
+
paths: ["/id"],
|
|
275
|
+
kind: cosmos_1.PartitionKeyKind.Hash,
|
|
276
|
+
version: 2,
|
|
277
|
+
},
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
282
|
+
console.log(`⚠️ Failed to recreate "${containerName}" with full partition key definition: ${message}`);
|
|
283
|
+
console.log("🔄 Retrying with simple partition key...");
|
|
284
|
+
await database.containers.createIfNotExists({
|
|
285
|
+
id: containerName,
|
|
286
|
+
partitionKey: {
|
|
287
|
+
paths: ["/id"],
|
|
288
|
+
},
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=dev-seeds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-seeds.js","sourceRoot":"","sources":["../../../src/cli/commands/dev-seeds.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsBpC,wBAAgB,uBAAuB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAEvE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAGnE;AAED,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAUA;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAW3G;AAiQD,eAAO,MAAM,UAAU,SAoBnB,CAAC"}
|
package/dist/cli/commands/dev.js
CHANGED
|
@@ -45,6 +45,7 @@ const fs = __importStar(require("fs"));
|
|
|
45
45
|
const os = __importStar(require("os"));
|
|
46
46
|
const cosmos_1 = require("@azure/cosmos");
|
|
47
47
|
const config_1 = require("../../core/config");
|
|
48
|
+
const dev_seeds_1 = require("./dev-seeds");
|
|
48
49
|
const package_manager_1 = require("../../utils/package-manager");
|
|
49
50
|
function buildFunctionsStartArgs(functionsPort) {
|
|
50
51
|
return ['start', '--port', functionsPort];
|
|
@@ -262,6 +263,7 @@ exports.devCommand = new commander_1.Command()
|
|
|
262
263
|
.option('--open', 'Open browser automatically', false)
|
|
263
264
|
.option('--verbose', 'Show verbose logs', false)
|
|
264
265
|
.option('--no-functions', 'Skip Azure Functions startup', false)
|
|
266
|
+
.option('--seed-env <environment>', 'Replace Cosmos DB Emulator data from dev-seeds/<environment> before startup')
|
|
265
267
|
.action(async (options) => {
|
|
266
268
|
// SwallowKit プロジェクトディレクトリかどうかを検証
|
|
267
269
|
(0, config_1.ensureSwallowKitProject)("dev");
|
|
@@ -278,14 +280,14 @@ async function initializeCosmosDB(databaseName) {
|
|
|
278
280
|
const localSettingsPath = path.join(functionsDir, 'local.settings.json');
|
|
279
281
|
if (!fs.existsSync(localSettingsPath)) {
|
|
280
282
|
console.log('⚠️ local.settings.json not found. Skipping Cosmos DB initialization.');
|
|
281
|
-
return;
|
|
283
|
+
return null;
|
|
282
284
|
}
|
|
283
285
|
const localSettings = JSON.parse(fs.readFileSync(localSettingsPath, 'utf-8'));
|
|
284
286
|
const connectionString = localSettings.Values?.CosmosDBConnection;
|
|
285
287
|
const dbName = localSettings.Values?.COSMOS_DB_DATABASE_NAME || databaseName;
|
|
286
288
|
if (!connectionString) {
|
|
287
289
|
console.log('⚠️ CosmosDBConnection not found in local.settings.json. Skipping Cosmos DB initialization.');
|
|
288
|
-
return;
|
|
290
|
+
return null;
|
|
289
291
|
}
|
|
290
292
|
console.log('🗄️ Initializing Cosmos DB...');
|
|
291
293
|
// Parse connection string
|
|
@@ -293,7 +295,7 @@ async function initializeCosmosDB(databaseName) {
|
|
|
293
295
|
const keyMatch = connectionString.match(/AccountKey=([^;]+)/);
|
|
294
296
|
if (!endpointMatch || !keyMatch) {
|
|
295
297
|
console.log('⚠️ Invalid CosmosDB connection string format.');
|
|
296
|
-
return;
|
|
298
|
+
return null;
|
|
297
299
|
}
|
|
298
300
|
const endpoint = endpointMatch[1];
|
|
299
301
|
const client = new cosmos_1.CosmosClient({
|
|
@@ -303,62 +305,52 @@ async function initializeCosmosDB(databaseName) {
|
|
|
303
305
|
// Create database if not exists
|
|
304
306
|
const { database } = await client.databases.createIfNotExists({ id: dbName });
|
|
305
307
|
console.log(`✅ Database "${dbName}" ready`);
|
|
306
|
-
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
// Try creating container with full partition key definition first
|
|
320
|
-
let containerCreated = false;
|
|
321
|
-
try {
|
|
322
|
-
console.log(`🔧 Creating container "${containerName}" with partition key /id...`);
|
|
323
|
-
const containerResponse = await database.containers.createIfNotExists({
|
|
324
|
-
id: containerName,
|
|
325
|
-
partitionKey: {
|
|
326
|
-
paths: ['/id'],
|
|
327
|
-
kind: cosmos_1.PartitionKeyKind.Hash,
|
|
328
|
-
version: 2
|
|
329
|
-
}
|
|
330
|
-
});
|
|
331
|
-
console.log(`✅ Container "${containerName}" ready (status: ${containerResponse.statusCode})`);
|
|
332
|
-
containerCreated = true;
|
|
333
|
-
}
|
|
334
|
-
catch (error) {
|
|
335
|
-
console.log(`⚠️ Failed with full partition key definition: ${error.message}`);
|
|
336
|
-
console.log(`🔄 Retrying with simple partition key...`);
|
|
308
|
+
const models = await (0, dev_seeds_1.loadProjectModels)();
|
|
309
|
+
for (const model of models) {
|
|
310
|
+
const containerName = (0, dev_seeds_1.getContainerNameForModel)(model);
|
|
311
|
+
// Try creating container with full partition key definition first
|
|
312
|
+
let containerCreated = false;
|
|
313
|
+
try {
|
|
314
|
+
console.log(`🔧 Creating container "${containerName}" with partition key /id...`);
|
|
315
|
+
const containerResponse = await database.containers.createIfNotExists({
|
|
316
|
+
id: containerName,
|
|
317
|
+
partitionKey: {
|
|
318
|
+
paths: ['/id'],
|
|
319
|
+
kind: cosmos_1.PartitionKeyKind.Hash,
|
|
320
|
+
version: 2
|
|
337
321
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
}
|
|
355
|
-
// Continue with other containers
|
|
322
|
+
});
|
|
323
|
+
console.log(`✅ Container "${containerName}" ready (status: ${containerResponse.statusCode})`);
|
|
324
|
+
containerCreated = true;
|
|
325
|
+
}
|
|
326
|
+
catch (error) {
|
|
327
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
328
|
+
console.log(`⚠️ Failed with full partition key definition: ${message}`);
|
|
329
|
+
console.log(`🔄 Retrying with simple partition key...`);
|
|
330
|
+
}
|
|
331
|
+
// If first attempt failed, try with simple partition key definition
|
|
332
|
+
if (!containerCreated) {
|
|
333
|
+
try {
|
|
334
|
+
const containerResponse = await database.containers.createIfNotExists({
|
|
335
|
+
id: containerName,
|
|
336
|
+
partitionKey: {
|
|
337
|
+
paths: ['/id']
|
|
356
338
|
}
|
|
339
|
+
});
|
|
340
|
+
console.log(`✅ Container "${containerName}" ready (status: ${containerResponse.statusCode})`);
|
|
341
|
+
}
|
|
342
|
+
catch (containerError) {
|
|
343
|
+
console.error(`❌ Failed to create container "${containerName}":`, containerError.message);
|
|
344
|
+
console.error(`Error code: ${containerError.code}`);
|
|
345
|
+
if (containerError.body) {
|
|
346
|
+
console.error(`Response body:`, JSON.stringify(containerError.body, null, 2));
|
|
357
347
|
}
|
|
348
|
+
// Continue with other containers
|
|
358
349
|
}
|
|
359
350
|
}
|
|
360
351
|
}
|
|
361
352
|
console.log('✅ Cosmos DB initialization complete\n');
|
|
353
|
+
return { endpoint, key: keyMatch[1], databaseName: dbName, models };
|
|
362
354
|
}
|
|
363
355
|
catch (error) {
|
|
364
356
|
console.error('⚠️ Cosmos DB initialization failed:', error.message);
|
|
@@ -366,6 +358,7 @@ async function initializeCosmosDB(databaseName) {
|
|
|
366
358
|
console.error('Stack trace:', error.stack);
|
|
367
359
|
}
|
|
368
360
|
console.log('💡 Make sure Cosmos DB Emulator is running');
|
|
361
|
+
return null;
|
|
369
362
|
}
|
|
370
363
|
}
|
|
371
364
|
async function startDevEnvironment(options) {
|
|
@@ -473,7 +466,18 @@ async function startDevEnvironment(options) {
|
|
|
473
466
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
474
467
|
const appName = packageJson.name || 'App';
|
|
475
468
|
const databaseName = `${appName.charAt(0).toUpperCase() + appName.slice(1)}Database`;
|
|
476
|
-
await initializeCosmosDB(databaseName);
|
|
469
|
+
const cosmosInitialization = await initializeCosmosDB(databaseName);
|
|
470
|
+
if (options.seedEnv && cosmosInitialization) {
|
|
471
|
+
await (0, dev_seeds_1.applyDevSeedEnvironment)({
|
|
472
|
+
client: new cosmos_1.CosmosClient({
|
|
473
|
+
endpoint: cosmosInitialization.endpoint,
|
|
474
|
+
key: cosmosInitialization.key,
|
|
475
|
+
}),
|
|
476
|
+
databaseName: cosmosInitialization.databaseName,
|
|
477
|
+
environment: options.seedEnv,
|
|
478
|
+
models: cosmosInitialization.models,
|
|
479
|
+
});
|
|
480
|
+
}
|
|
477
481
|
console.log('');
|
|
478
482
|
console.log('🚀 Starting Azure Functions...');
|
|
479
483
|
if (backendLanguage === 'typescript') {
|