@leaddreamer/inventorylogic 0.0.3-beta.79 → 0.0.3-beta.80
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 +16 -20
- package/business/Utilities/index.js +1 -0
- package/business/Utilities/other.js +1 -3
- package/business/Utilities/promise-queue/index.js +183 -150
- package/business/Utilities/promise-queue/new.js +231 -0
- package/dist/InventoryLogic.0ac93278.js +35 -0
- package/dist/InventoryLogic.0ac93278.js.map +1 -0
- package/dist/InventoryLogic.31f6d549.js +152 -0
- package/dist/InventoryLogic.31f6d549.js.map +1 -0
- package/dist/InventoryLogic.35827495.js +285 -0
- package/dist/InventoryLogic.35827495.js.map +1 -0
- package/dist/InventoryLogic.37dfff3e.js +72 -0
- package/dist/InventoryLogic.37dfff3e.js.map +1 -0
- package/dist/InventoryLogic.4206cb15.js +213 -0
- package/dist/InventoryLogic.4206cb15.js.map +1 -0
- package/dist/InventoryLogic.44193a77.js +35 -0
- package/dist/InventoryLogic.44193a77.js.map +1 -0
- package/dist/InventoryLogic.46ca6768.js +131 -0
- package/dist/InventoryLogic.46ca6768.js.map +1 -0
- package/dist/InventoryLogic.4d012935.js +151 -0
- package/dist/InventoryLogic.4d012935.js.map +1 -0
- package/dist/InventoryLogic.57f24f5f.js +155 -0
- package/dist/InventoryLogic.57f24f5f.js.map +1 -0
- package/dist/InventoryLogic.59be76a4.js +184 -0
- package/dist/InventoryLogic.59be76a4.js.map +1 -0
- package/dist/InventoryLogic.70925a32.js +375 -0
- package/dist/InventoryLogic.70925a32.js.map +1 -0
- package/dist/InventoryLogic.72fcf301.js +6 -0
- package/dist/InventoryLogic.72fcf301.js.map +1 -0
- package/dist/InventoryLogic.7741caec.js +375 -0
- package/dist/InventoryLogic.7741caec.js.map +1 -0
- package/dist/InventoryLogic.78480e5e.js +152 -0
- package/dist/InventoryLogic.78480e5e.js.map +1 -0
- package/dist/InventoryLogic.80d0e568.js +135 -0
- package/dist/InventoryLogic.80d0e568.js.map +1 -0
- package/dist/InventoryLogic.8a273d2e.js +110 -0
- package/dist/InventoryLogic.8a273d2e.js.map +1 -0
- package/dist/InventoryLogic.8addb055.js +202 -0
- package/dist/InventoryLogic.8addb055.js.map +1 -0
- package/dist/InventoryLogic.9dee46ea.js +6 -0
- package/dist/InventoryLogic.9dee46ea.js.map +1 -0
- package/dist/InventoryLogic.b90f66ea.js +124 -0
- package/dist/InventoryLogic.b90f66ea.js.map +1 -0
- package/dist/InventoryLogic.bb447b4c.js +39 -0
- package/dist/InventoryLogic.bb447b4c.js.map +1 -0
- package/dist/InventoryLogic.d27e84a7.js +75 -0
- package/dist/InventoryLogic.d27e84a7.js.map +1 -0
- package/dist/InventoryLogic.d69ad127.js +217 -0
- package/dist/InventoryLogic.d69ad127.js.map +1 -0
- package/dist/InventoryLogic.e03e6b07.js +245 -0
- package/dist/InventoryLogic.e03e6b07.js.map +1 -0
- package/dist/InventoryLogic.f276f76c.js +213 -0
- package/dist/InventoryLogic.f276f76c.js.map +1 -0
- package/dist/InventoryLogic.f4627c8a.js +160 -0
- package/dist/InventoryLogic.f4627c8a.js.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/index.js +1 -2
- package/package.json +7 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["business/BusinessData/index.js"],"sourcesContent":["/**\n * Functions for managing (potentially)private data for an organization.\n * Unified structure as a sub-record of organization, or CityManager accounts\n * @module BusinessData\n */\nimport {\n fetchRecord,\n writeRecord,\n typedWrite,\n writeBack,\n deleteRecordByRefPath,\n} from \"@leaddreamer/firebase-wrapper\";\nimport { Forms, fillForm } from \"@leaddreamer/staticforms\";\nimport {\n BUSINESS,\n BUSINESSDATA,\n BUSINESS_TYPE,\n ADDRESSES,\n USER,\n MCC,\n} from \"../boilerplate/index.js\";\nimport { fetchAddresses } from \"../Addresses/index.js\";\n\n//////////////////////////////////////////////////////////////////////\n// definitions\n\n/**\n * @external AddressType\n */\n/**\n * @typedef {object} contact\n * @property {?string} contact.Id\n * @property {!string} contact.first_name\n * @property {!string} contact.last_name\n * @property {!string} contact.tel\n * @property {?string} contact.email - must be filled in to make profile public\n */\n/**\n * @typedef {object} BusinessData\n * @property {?string} email - must be filled in to make profile public\n * @property {contact} contact\n * @property {!string} tel\n * @property {string} business_type\n * @property {AddressType} business_address\n * @property {AddressType} mailing_address\n * @property {AddressType} billing_address\n */\n/**\n * @constant\n * @type {BusinessData}\n * @default\n */\nconst BusinessDefault = {\n Id: null,\n email: null,\n business_type: null,\n contact: null,\n business_address: null,\n mailing_address: null,\n billing_address: null,\n tel: null,\n mcc: null,\n tax_rate: null,\n //tax_id: null,\n openIssues: false,\n};\n\n/**\n * @constant\n * @type {BusinessData}\n * @default\n */\nconst BusinessAccountForm = {\n refPath: \"hidden:text\",\n email: \"email\",\n business_type: `lookup:${BUSINESS_TYPE}`,\n contact: `object:${USER}`,\n business_address: `lookupLink:${ADDRESSES}`,\n mailing_address: `lookupLink:${ADDRESSES}`,\n billing_address: `lookupLink:${ADDRESSES}`,\n tel: \"tel\",\n mcc: `lookup:${MCC}`,\n};\n\nForms.Base[BUSINESSDATA] = BusinessDefault;\nForms.BaseForm[BUSINESSDATA] = BusinessAccountForm;\nForms.AccountForm[BUSINESSDATA] = BusinessAccountForm;\n\n//////////////////////////////////////////////////////////////////////\n// Utilities\n\n/**\n * Fetches a fulll object representation of an account, including BusinessData\n * @param {AccountType} account\n * @returns {Promise.AccountType}\n */\nexport async function fetchFullAccount(account) {\n const BusinessData = await fetchBusinessData(account);\n\n account.business = BusinessData;\n\n return account;\n}\n\n/**\n * Fetches the BusinessData (corporate, addresses, etc) for an account\n * @param {AccountType} account\n * @returns {Promise.BusinessData}\n */\nexport async function fetchBusinessData(account) {\n let addresses = [];\n try {\n addresses = await fetchAddresses(account);\n } catch (err) {}\n const addressMap = new Map();\n if (addresses.length) {\n addresses.forEach((address) => {\n addressMap.set(address.Id, address);\n });\n }\n\n const BusinessData = await fetchRecord(\n BUSINESSDATA,\n account.Id,\n account.refPath,\n );\n\n let addressEntries = {};\n [\"business_address\", \"billing_address\", \"mailing_address\"].forEach(\n (entry) => {\n const isLink =\n entry && BusinessData[entry] && !BusinessData[entry]?.address_line_1;\n if (isLink) {\n addressEntries[entry] = {\n ...addressMap.get(BusinessData[entry]),\n };\n }\n },\n ); //hacky way to repeat same effort\n\n return {\n ...BusinessData,\n ...addressEntries,\n };\n}\n\n/**\n * Composes a URL for an \"account page\" from the account, and passed base URL\n * @param {!AccountType} account\n * @param {!string} origin base URL for the application\n * @returns {string} full URL for business accouont\n */\nexport function accountPage(account, origin) {\n return `${origin}/${BUSINESS}/Account`; //Leads to LOGGED IN organization account page\n}\n\n/**\n * @external WriteBatch\n * @typedef {WriteBatch|Transaction|void} ChainType\n */\n\n/**\n * @async\n * @function\n * @static\n * Creates the Business information document\n * @param {AccountType} account\n * @param {?ChainType} batch - batching object. Transaction will be added to the batch\n * @returns {Promise<ChainType>} WriteBatch, Transaction or Void\n */\nexport async function createBusinessData(account, batch = null) {\n return typedWrite(\n {\n ...Forms.Base[BUSINESSDATA], //base fields with defaults\n ...fillForm(account, BUSINESSDATA), //sanitize passed data\n }, //data\n account, //parent\n BUSINESSDATA, //type\n batch,\n );\n}\n\n/**\n * Writes the \"Business\" data to the database\n * @param {BusinessData} businessData\n * @returns {Promise<BusinessData>}\n */\nexport async function saveBusinessData(businessData, batch = null) {\n return writeBack(businessData, batch);\n}\n\n/**\n * Deletes a BusinessData record (rarely used if ever)\n * @param {BusinessData} businessData\n * @param {!string} businessData.refPath\n * @returns {Promise<void>}\n */\nexport async function deleteBusinessData(businessData, batch = null) {\n return deleteRecordByRefPath(businessData.refPath, batch);\n}\n\n/**\n * creates the \"base path\" (refPath) to store addresses based on an account (refPath)\n * @param {Record} account\n * @param {!string} account.refPath\n * @returns {string}\n */\nexport function businessDataPath(account) {\n return `${account.refPath}/${BUSINESSDATA}/${account.Id}`;\n}\n\n/**\n * verifies that all needed information has been filled in\n * @param {AccountType} account\n * @param {BusinessData} businessData record\n * @returns {Boolean}\n */\nexport function profileComplete(account, businessData) {\n if (!businessData?.business_address) return false;\n if (!businessData?.billing_address) return false;\n if (!businessData?.mailing_address) return false;\n if (!businessData?.email) return false;\n if (!businessData?.tel) return false;\n if (!account?.website) return false;\n if (!(account?.name || account?.corporate)) return false;\n return true;\n}\n\n/**\n * verifies that all needed information has been filled in\n * @param {AccountType} account\n * @param {BusinessData} businessData record\n * @returns {string|null}\n */\nexport function profileIncomplete(account, businessData) {\n let problem_string = \"\";\n if (!businessData?.business_address) {\n problem_string = problem_string.concat(`=> Business Address Missing\\n`);\n }\n if (!businessData?.billing_address) {\n problem_string = problem_string.concat(`=> Billing Address Missing\\n`);\n }\n if (!businessData?.mailing_address) {\n problem_string = problem_string.concat(`=> Mailing Address Missing\\n`);\n }\n if (!businessData?.email) {\n problem_string = problem_string.concat(`=> Business Email Missing\\n`);\n }\n if (!businessData?.tel) {\n problem_string = problem_string.concat(`=> Business Telephone Missing\\n`);\n }\n if (!account?.website) {\n problem_string = problem_string.concat(`=> Business Website Missing\\n`);\n }\n if (!(account?.name || account?.corporate)) {\n problem_string = problem_string.concat(\n `=> Business and/or Corporate Name Missing\\n`,\n );\n }\n return problem_string.length ? problem_string : null;\n}\n\n/**\n * Sets the \"openIssues\" flag in an account's BUSINESSDATA record\n * The account's refPath is attached to the Payment system's record, and\n * used here to find the Payment Account\n * @param {BusinessData} businessData\n * @returns {Promise.boolean}\n */\nexport async function setOpenIssues(businessData) {\n return writeRecord(\n BUSINESSDATA,\n {\n ...businessData,\n openIssues: true,\n },\n businessData.refPath,\n null,\n true,\n );\n}\n\n/**\n * Clears the \"openIssues\" flag in an account's BUSINESSDATA record\n * The account's refPath is attached to the Payment system's record, and\n * used here to find the Payment Account\n * @param {BusinessData} businessData\n * @returns {Promise.boolean}\n */\nexport async function clearOpenIssues(businessData) {\n return writeRecord(\n BUSINESSDATA,\n {\n ...businessData,\n openIssues: false,\n },\n businessData.refPath,\n null,\n true,\n );\n}\n"],"names":[],"version":3,"file":"InventoryLogic.57f24f5f.js.map"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typedefs, constants, support functions and database operations related to Promise getQueueSize
|
|
3
|
+
* Thes are useful for scheduling large serial asynchronous operations
|
|
4
|
+
* @module PromiseQueue
|
|
5
|
+
*/ /**
|
|
6
|
+
* Creates a new rate limited queue. The queue is created with stopped state, i.e. you have to call start() to run jobs.
|
|
7
|
+
* @class
|
|
8
|
+
*/ class $d403d40112d3687c$export$e869d3bcedcd9592 {
|
|
9
|
+
/**
|
|
10
|
+
* @param {number} maxCallsPerSecond - The rate limit of this queue in maximum calls per seconds which may be executed at any time. Pass values less than 1 to have less than one call per second, e.g. 1/3 for 3 one call in three seconds at maximum.
|
|
11
|
+
* @param {callback} logger optional logger function for errors
|
|
12
|
+
* @constructor
|
|
13
|
+
*/ constructor(maxCallsPerSecond = 1, logger){
|
|
14
|
+
/**
|
|
15
|
+
* The rate limit of this queue in maximum calls per seconds
|
|
16
|
+
* which may be executed at any time. Pass values less than 1
|
|
17
|
+
* to have less than one call per second, e.g. 1/3 for 3 one
|
|
18
|
+
* call in three seconds at maximum.
|
|
19
|
+
* @type {float}
|
|
20
|
+
*/ this.maxCallsPerSecond = typeof maxCallsPerSecond === "undefined" ? 1 : maxCallsPerSecond;
|
|
21
|
+
/**
|
|
22
|
+
* optional logger function for errors
|
|
23
|
+
* @type {callback}
|
|
24
|
+
*/ this.logger = logger;
|
|
25
|
+
/**
|
|
26
|
+
* lists of tasks to be processed, in order, in the queue
|
|
27
|
+
* @type {Array.callback}
|
|
28
|
+
*/ this.tasks = [];
|
|
29
|
+
/**
|
|
30
|
+
* flag to indicate queue processing is active
|
|
31
|
+
* @type {boolean}
|
|
32
|
+
*/ this.isActive = false;
|
|
33
|
+
/**
|
|
34
|
+
* pacing for queue processing / rate limiting
|
|
35
|
+
* @type {float}
|
|
36
|
+
*/ this.jobIntervalMillis = 1000 / maxCallsPerSecond;
|
|
37
|
+
/**
|
|
38
|
+
* timestamp of start of last task
|
|
39
|
+
* @type {time}
|
|
40
|
+
*/ this.lastTaskTimestamp = null;
|
|
41
|
+
/**
|
|
42
|
+
* @type {string}
|
|
43
|
+
*/ this.currentTaskTimeoutId = null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Processes the next task and returns the id of the time used to wait for the next invocation of this method.
|
|
47
|
+
* @private
|
|
48
|
+
*/ updateTaskSchedule() {
|
|
49
|
+
if (this.logger && this.logger.debug) this.logger.debug("PromiseQueue.updateTaskSchedule");
|
|
50
|
+
if (this.isEmpty() || this.isStopped()) return;
|
|
51
|
+
const queue = this;
|
|
52
|
+
function processNextTask() {
|
|
53
|
+
if (queue.logger && queue.logger.debug) queue.logger.debug("PromiseQueue.processNextTask", queue.tasks.length);
|
|
54
|
+
var nextTaskItem = queue.tasks.shift();
|
|
55
|
+
if (nextTaskItem) try {
|
|
56
|
+
const result = nextTaskItem.task.call();
|
|
57
|
+
if (queue.logger && queue.logger.debug) queue.logger.debug("Resolving queued promise", result, result instanceof Promise);
|
|
58
|
+
nextTaskItem.resolve(result);
|
|
59
|
+
} catch (e) {
|
|
60
|
+
queue.logger.info("rejecting queued promise result", e);
|
|
61
|
+
nextTaskItem.reject(e);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function scheduleNext(timeoutMillisOverride) {
|
|
65
|
+
if (queue.logger && queue.logger.debug) queue.logger.debug("PromiseQueue.scheduleNext", timeoutMillisOverride);
|
|
66
|
+
if (queue.isEmpty()) {
|
|
67
|
+
queue.currentTaskTimeoutId = null;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
queue.currentTaskTimeoutId = setTimeout(function() {
|
|
71
|
+
queue.lastTaskTimestamp = Date.now();
|
|
72
|
+
processNextTask();
|
|
73
|
+
scheduleNext(queue.jobIntervalMillis);
|
|
74
|
+
}, timeoutMillisOverride);
|
|
75
|
+
}
|
|
76
|
+
if (this.currentTaskTimeoutId == null) {
|
|
77
|
+
if (this.lastTaskTimestamp) {
|
|
78
|
+
let passedTime = Date.now() - this.lastTaskTimestamp;
|
|
79
|
+
if (passedTime > this.jobIntervalMillis) scheduleNext(this.jobIntervalMillis);
|
|
80
|
+
else scheduleNext(Math.max(0, this.jobIntervalMillis - passedTime));
|
|
81
|
+
} else scheduleNext(0);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Starts the task processing of this queue.
|
|
86
|
+
*
|
|
87
|
+
* If it is already started, then false will be returned.
|
|
88
|
+
* If it is not yet started then the first task will be processed in the background and true will be returned.
|
|
89
|
+
*
|
|
90
|
+
* @return {boolean} true if this queue wasn't started before and now started to process tasks.
|
|
91
|
+
*/ start() {
|
|
92
|
+
if (this.isActive) return false;
|
|
93
|
+
this.isActive = true;
|
|
94
|
+
this.updateTaskSchedule();
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Stops the processing of this queue.
|
|
99
|
+
* @return true if the queue was started and is now stopped. false if it was already stopped.
|
|
100
|
+
*/ stop() {
|
|
101
|
+
if (this.isActive) {
|
|
102
|
+
this.isActive = false;
|
|
103
|
+
if (this.currentTaskTimeoutId) {
|
|
104
|
+
clearInterval(this.currentTaskTimeoutId);
|
|
105
|
+
this.currentTaskTimeoutId = null;
|
|
106
|
+
this.lastTaskTimestamp = null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
getMaxCallsPerSecond() {
|
|
111
|
+
return this.maxCallsPerSecond;
|
|
112
|
+
}
|
|
113
|
+
isStarted() {
|
|
114
|
+
return this.isActive;
|
|
115
|
+
}
|
|
116
|
+
isStopped() {
|
|
117
|
+
return !this.isStarted();
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* @returns {boolean} true if this queue is currently empty, i.e. if it has no tasks in the queue.
|
|
121
|
+
*/ isEmpty() {
|
|
122
|
+
return this.tasks.length === 0;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* @returns {boolean} true if this queue has one or more entries.
|
|
126
|
+
*/ isNotEmpty() {
|
|
127
|
+
return !this.isEmpty();
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* @param {function} task - The task to add.
|
|
131
|
+
* @param {boolean} append - if the task should be appended or prepended to the list of queued tasks
|
|
132
|
+
* @return {Promise} A promise which is resolved/rejected when the task was executed by the queue.
|
|
133
|
+
*/ async add(task, append) {
|
|
134
|
+
var self = this;
|
|
135
|
+
var promise = new Promise(function(resolve, reject) {
|
|
136
|
+
var newTaskItem = {
|
|
137
|
+
task: task,
|
|
138
|
+
resolve: resolve,
|
|
139
|
+
reject: reject
|
|
140
|
+
};
|
|
141
|
+
if (self.isEmpty() || append) self.tasks.push(newTaskItem);
|
|
142
|
+
else self.tasks.unshift(newTaskItem);
|
|
143
|
+
});
|
|
144
|
+
self.updateTaskSchedule();
|
|
145
|
+
return promise;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Appends a new task at the end of the queue.
|
|
149
|
+
* @param {function} task - The task to perform. This function will be called with no arguments.
|
|
150
|
+
* @return {Promise} A promise which is resolved/rejected When the task was executed by the queue
|
|
151
|
+
*/ async append(task) {
|
|
152
|
+
return this.add(task, true);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Adds a new task as first item in the queue.
|
|
156
|
+
* @param task
|
|
157
|
+
* @return {Promise} A promise which is resolved/rejected When the task was executed by the queue
|
|
158
|
+
*/ async prepend(task) {
|
|
159
|
+
return this.add(task, false);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Removes the task from the qeueue. If the task is contained more than one time then all occurrences will be removed.
|
|
163
|
+
* @param {function} task - The task to remove.
|
|
164
|
+
* @return {number} - The number of items which were removed.
|
|
165
|
+
*/ remove(task) {
|
|
166
|
+
if (this.isEmpty()) return 0;
|
|
167
|
+
var removedItems = 0;
|
|
168
|
+
for(var i = this.tasks.length - 1; i >= 0; i--)if (this.tasks[i].task === task) {
|
|
169
|
+
this.tasks.splice(i, 1);
|
|
170
|
+
removedItems++;
|
|
171
|
+
}
|
|
172
|
+
return removedItems;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* @returns {Number} - The number of queued/waiting tasks in the queue.
|
|
176
|
+
*/ getQueueSize() {
|
|
177
|
+
return this.tasks.length;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
var $d403d40112d3687c$export$2e2bcd8739ae039 = PromiseQueue = new $d403d40112d3687c$export$e869d3bcedcd9592(1, null);
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
export {$d403d40112d3687c$export$e869d3bcedcd9592 as PromiseQueueClass, $d403d40112d3687c$export$2e2bcd8739ae039 as default};
|
|
184
|
+
//# sourceMappingURL=InventoryLogic.59be76a4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["business/Utilities/promise-queue/index.js"],"sourcesContent":["/**\n * Typedefs, constants, support functions and database operations related to Promise getQueueSize\n * Thes are useful for scheduling large serial asynchronous operations\n * @module PromiseQueue\n */\n/**\n * Creates a new rate limited queue. The queue is created with stopped state, i.e. you have to call start() to run jobs.\n * @class\n */\nexport class PromiseQueueClass {\n /**\n * @param {number} maxCallsPerSecond - The rate limit of this queue in maximum calls per seconds which may be executed at any time. Pass values less than 1 to have less than one call per second, e.g. 1/3 for 3 one call in three seconds at maximum.\n * @param {callback} logger optional logger function for errors\n * @constructor\n */\n constructor(maxCallsPerSecond=1, logger) {\n /**\n * The rate limit of this queue in maximum calls per seconds\n * which may be executed at any time. Pass values less than 1\n * to have less than one call per second, e.g. 1/3 for 3 one\n * call in three seconds at maximum.\n * @type {float}\n */\n this.maxCallsPerSecond =\n typeof maxCallsPerSecond === \"undefined\" ? 1 : maxCallsPerSecond;\n /**\n * optional logger function for errors\n * @type {callback}\n */\n this.logger = logger;\n\n /**\n * lists of tasks to be processed, in order, in the queue\n * @type {Array.callback}\n */\n this.tasks = [];\n /**\n * flag to indicate queue processing is active\n * @type {boolean}\n */\n this.isActive = false;\n /**\n * pacing for queue processing / rate limiting\n * @type {float}\n */\n this.jobIntervalMillis = 1000 / maxCallsPerSecond;\n /**\n * timestamp of start of last task\n * @type {time}\n */\n this.lastTaskTimestamp = null;\n /**\n * @type {string}\n */\n this.currentTaskTimeoutId = null;\n }\n\n /**\n * Processes the next task and returns the id of the time used to wait for the next invocation of this method.\n * @private\n */\n updateTaskSchedule() {\n if (this.logger && this.logger.debug) {\n this.logger.debug(\"PromiseQueue.updateTaskSchedule\");\n }\n\n if (this.isEmpty() || this.isStopped()) {\n return;\n }\n\n const queue = this;\n\n function processNextTask() {\n if (queue.logger && queue.logger.debug) {\n queue.logger.debug(\"PromiseQueue.processNextTask\", queue.tasks.length);\n }\n\n var nextTaskItem = queue.tasks.shift();\n if (nextTaskItem) {\n try {\n const result = nextTaskItem.task.call();\n\n if (queue.logger && queue.logger.debug) {\n queue.logger.debug(\n \"Resolving queued promise\",\n result,\n result instanceof Promise\n );\n }\n\n nextTaskItem.resolve(result);\n } catch (e) {\n queue.logger.info(\"rejecting queued promise result\", e);\n nextTaskItem.reject(e);\n }\n }\n }\n\n function scheduleNext(timeoutMillisOverride) {\n if (queue.logger && queue.logger.debug) {\n queue.logger.debug(\"PromiseQueue.scheduleNext\", timeoutMillisOverride);\n }\n\n if (queue.isEmpty()) {\n queue.currentTaskTimeoutId = null;\n return;\n }\n\n queue.currentTaskTimeoutId = setTimeout(function () {\n queue.lastTaskTimestamp = Date.now();\n processNextTask();\n\n scheduleNext(queue.jobIntervalMillis);\n }, timeoutMillisOverride);\n }\n\n if (this.currentTaskTimeoutId == null) {\n if (this.lastTaskTimestamp) {\n let passedTime = Date.now() - this.lastTaskTimestamp;\n if (passedTime > this.jobIntervalMillis) {\n scheduleNext(this.jobIntervalMillis);\n } else {\n scheduleNext(Math.max(0, this.jobIntervalMillis - passedTime));\n }\n } else {\n scheduleNext(0);\n }\n }\n };\n\n /**\n * Starts the task processing of this queue.\n *\n * If it is already started, then false will be returned.\n * If it is not yet started then the first task will be processed in the background and true will be returned.\n *\n * @return {boolean} true if this queue wasn't started before and now started to process tasks.\n */\n start() {\n if (this.isActive) {\n return false;\n }\n\n this.isActive = true;\n\n this.updateTaskSchedule();\n\n return true;\n };\n\n /**\n * Stops the processing of this queue.\n * @return true if the queue was started and is now stopped. false if it was already stopped.\n */\n stop() {\n if (this.isActive) {\n this.isActive = false;\n\n if (this.currentTaskTimeoutId) {\n clearInterval(this.currentTaskTimeoutId);\n this.currentTaskTimeoutId = null;\n this.lastTaskTimestamp = null;\n }\n }\n };\n\n getMaxCallsPerSecond() {\n return this.maxCallsPerSecond;\n };\n\n isStarted() {\n return this.isActive;\n };\n\n isStopped() {\n return !this.isStarted();\n };\n\n /**\n * @returns {boolean} true if this queue is currently empty, i.e. if it has no tasks in the queue.\n */\n isEmpty() {\n return this.tasks.length === 0;\n };\n\n /**\n * @returns {boolean} true if this queue has one or more entries.\n */\n isNotEmpty() {\n return !this.isEmpty();\n };\n\n /**\n * @param {function} task - The task to add.\n * @param {boolean} append - if the task should be appended or prepended to the list of queued tasks\n * @return {Promise} A promise which is resolved/rejected when the task was executed by the queue.\n */\n async add(task, append) {\n var self = this;\n\n var promise = new Promise(function (resolve, reject) {\n var newTaskItem = { task: task, resolve: resolve, reject: reject };\n\n if (self.isEmpty() || append) {\n self.tasks.push(newTaskItem);\n } else {\n self.tasks.unshift(newTaskItem);\n }\n });\n\n self.updateTaskSchedule();\n\n return promise;\n };\n\n /**\n * Appends a new task at the end of the queue.\n * @param {function} task - The task to perform. This function will be called with no arguments.\n * @return {Promise} A promise which is resolved/rejected When the task was executed by the queue\n */\n async append(task) {\n return this.add(task, true);\n };\n\n /**\n * Adds a new task as first item in the queue.\n * @param task\n * @return {Promise} A promise which is resolved/rejected When the task was executed by the queue\n */\n async prepend(task) {\n return this.add(task, false);\n };\n\n /**\n * Removes the task from the qeueue. If the task is contained more than one time then all occurrences will be removed.\n * @param {function} task - The task to remove.\n * @return {number} - The number of items which were removed.\n */\n remove(task) {\n if (this.isEmpty()) {\n return 0;\n }\n\n var removedItems = 0;\n for (var i = this.tasks.length - 1; i >= 0; i--) {\n if (this.tasks[i].task === task) {\n this.tasks.splice(i, 1);\n removedItems++;\n }\n }\n\n return removedItems;\n };\n\n /**\n * @returns {Number} - The number of queued/waiting tasks in the queue.\n */\n getQueueSize() {\n return this.tasks.length;\n };\n\n};\n\nexport default PromiseQueue = new PromiseQueueClass(1, null);\n"],"names":[],"version":3,"file":"InventoryLogic.59be76a4.js.map"}
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import {ISBN_LENGTH as $fefa9c41cb73ae0b$export$dbb3cd0a4caa6254, MARKUPS as $fefa9c41cb73ae0b$export$1bfdae073fb20e6c, PRODUCT as $fefa9c41cb73ae0b$export$e36553b0ff5db35a} from "./InventoryLogic.d27e84a7.js";
|
|
2
|
+
import {typedRecordFromChild as $9ab66828811feaa2$export$9536a88c96a1be48} from "./InventoryLogic.31f6d549.js";
|
|
3
|
+
import {GoogleAPIProductMap as $e409a6a48e9bf1c0$export$4059922dac929494} from "./InventoryLogic.b90f66ea.js";
|
|
4
|
+
import {JSONProductFeedToItemMapping as $63eb266a363bf697$export$8f68ab01093b41d6, squarespaceFeedTest as $63eb266a363bf697$export$c736243f342fb27b} from "./InventoryLogic.e03e6b07.js";
|
|
5
|
+
import {updateRecord as $lRpTb$updateRecord} from "@leaddreamer/firebase-wrapper";
|
|
6
|
+
import {Forms as $lRpTb$Forms, fillForm as $lRpTb$fillForm} from "@leaddreamer/staticforms";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Typedefs, constants, support functions and database operations related to Products
|
|
10
|
+
* @module Product
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
//////////////////////////////////////////////////////////////////////
|
|
18
|
+
// Constants
|
|
19
|
+
/**
|
|
20
|
+
* "recipe" related values - build-stage markups, product/project Flag, created/modified dates
|
|
21
|
+
* @typedef {object} Recipe_Data
|
|
22
|
+
* @property {module:Markups~Stage} markups
|
|
23
|
+
* @property {boolean} projectQ flag for product/project
|
|
24
|
+
* @property {dateTime} created
|
|
25
|
+
* @property {dateTime} modified
|
|
26
|
+
*/ /**
|
|
27
|
+
* A list of attributes for a product
|
|
28
|
+
* @typedef {Array.String} AttributeList
|
|
29
|
+
*/ /**
|
|
30
|
+
* Array of attribute name/value pairs
|
|
31
|
+
* @typedef {object} AttributeValue
|
|
32
|
+
* @property {string} attibuteName attribute name from attribute list
|
|
33
|
+
* @property {string} value value for the particular attribute
|
|
34
|
+
*/ /**
|
|
35
|
+
* @typedef
|
|
36
|
+
*/ /**
|
|
37
|
+
* Image Descriptor
|
|
38
|
+
* @typedef {object} ProductImage
|
|
39
|
+
* @property {string} altText alt text for the image - SEO etc
|
|
40
|
+
* @property {Array.string} availableFormats Available image sizes.
|
|
41
|
+
* @property {string} id unique id for this productImage
|
|
42
|
+
* @property {integer} orderIndex Position of the image in the product's image list.
|
|
43
|
+
* @property {object} originalSize Image size when first uploaded.
|
|
44
|
+
* @property {MetaData} seoOptions
|
|
45
|
+
* @property {string} URL Absolute URL of the hosted image.
|
|
46
|
+
*/ /**
|
|
47
|
+
* a Brand Object
|
|
48
|
+
* @typedef {object} BrandObject
|
|
49
|
+
* @property {?string} Id Database Id of document (redundant for convenience)
|
|
50
|
+
* @property {?string} refPath if from database, full path to document
|
|
51
|
+
* @property {?AggregateRatingsValue} aggregateRating
|
|
52
|
+
* @property {?URL|ImageObject} logo
|
|
53
|
+
* @property {ReviewObject} review A review of the item. Supersedes reviews
|
|
54
|
+
* @property {text} slogan A slogan or motto associated with the item.
|
|
55
|
+
* @property {Name} name The name of the brand.
|
|
56
|
+
*/ /**
|
|
57
|
+
* Currency Description ISO 4217 currency code
|
|
58
|
+
* @typedef {object} CurrencyDescription
|
|
59
|
+
* @property {string} currencyCode
|
|
60
|
+
* @property {integer} defaultFractionDigits
|
|
61
|
+
* @property {string} displayName
|
|
62
|
+
* @property {string} numericCodeAsString
|
|
63
|
+
* @property {string} symbol
|
|
64
|
+
*/ /**
|
|
65
|
+
* Monetary Value Specification
|
|
66
|
+
* @typedef {object} MonetaryValue
|
|
67
|
+
* @property {CurrencyDescription} currencyDescription
|
|
68
|
+
* @property {decimal} value Decimal monetary value
|
|
69
|
+
* @property {Date} effectiveDate
|
|
70
|
+
*/ /**
|
|
71
|
+
* Pricing Object
|
|
72
|
+
* @typedef {object} FullProductPricing
|
|
73
|
+
* @property {MonetaryValue} basePrice
|
|
74
|
+
* @property {boolean} onSale
|
|
75
|
+
* @property {MonetaryValue} salePrice
|
|
76
|
+
*/ /**
|
|
77
|
+
* Dimensions Object
|
|
78
|
+
* @typedef {object} ProductDimensions
|
|
79
|
+
* @property {float} height
|
|
80
|
+
* @property {float} width
|
|
81
|
+
* @property {float} length
|
|
82
|
+
* @property {text} unit //ProductDimensionsUnit
|
|
83
|
+
*/ /**
|
|
84
|
+
* Price Object
|
|
85
|
+
* @typedef {object} PriceObject
|
|
86
|
+
*
|
|
87
|
+
*/ /**
|
|
88
|
+
* Weight Object
|
|
89
|
+
* @typedef {object} ProductWeight
|
|
90
|
+
* @property {text} unit //ProductWeightUnitEnum
|
|
91
|
+
* @property {float} value
|
|
92
|
+
*/ /**
|
|
93
|
+
* Measurements of the variant when it's shipped. Present for PHYSICAL products only.
|
|
94
|
+
* @typedef {object} ProductMeasurements
|
|
95
|
+
* @property {ProductDimensions} dimensions
|
|
96
|
+
* @property {ProductWeight} weight
|
|
97
|
+
*/ /**
|
|
98
|
+
* @typedef {object} QuantitativeValue
|
|
99
|
+
* @property {Boolean | Number | text | StructuredValue} value
|
|
100
|
+
* The value of a QuantitativeValue (including Observation) or property value node.
|
|
101
|
+
* * For QuantitativeValue and MonetaryAmount, the recommended type for values is 'Number'.
|
|
102
|
+
* * For PropertyValue, it can be 'Text', 'Number', 'Boolean', or 'StructuredValue'.
|
|
103
|
+
* * Use values from 0123456789 (Unicode 'DIGIT ZERO' (U+0030) to 'DIGIT NINE' (U+0039)) rather than superficially similar Unicode symbols.
|
|
104
|
+
* * Use '.' (Unicode 'FULL STOP' (U+002E)) rather than ',' to indicate a decimal point. Avoid using these symbols as a readability separator.
|
|
105
|
+
* @property {number} maxValue The upper value of some characteristic or property.
|
|
106
|
+
* @property {number} minValue The lower value of some characteristic or property.
|
|
107
|
+
* @property {?Text} unitText A string or text indicating the unit of measurement. Useful if you cannot provide a standard unit code for unitCode
|
|
108
|
+
* @property {?Text | URL} unitCode
|
|
109
|
+
* The unit of measurement given using the UN/CEFACT Common Code (3 characters) or a URL. Other codes than the UN/CEFACT Common Code may be used with a prefix followed by a colon
|
|
110
|
+
*
|
|
111
|
+
*/ /**
|
|
112
|
+
* @typedef {object} SizeSpecification
|
|
113
|
+
* @property {Text} type "SizeSpecification"
|
|
114
|
+
* @property {QuantitativeValue} hasMeasurement
|
|
115
|
+
* @property {Array.SizeGroupEnumeration|SizeGroupEnumeration|Text} sizeGroup
|
|
116
|
+
* The size group (also known as "size type") for a product's size. Size groups are common in the fashion industry to define size
|
|
117
|
+
* segments and suggested audiences for wearable products. Multiple values can be combined, for example "men's big and tall", "petite maternity" or "regular".
|
|
118
|
+
* @property {Array.SizeSystemEnumeration|SizeSystemEnumeration|Text} sizeSystem
|
|
119
|
+
* The size system used to identify a product's size. Typically either a standard (for example, "GS1" or "ISO-EN13402"), country
|
|
120
|
+
* code (for example "US" or "JP"), or a measuring system (for example "Metric" or "Imperial").
|
|
121
|
+
* @property {QuantitativeValue} suggestedAge The age or age range for the intended audience or user, for example 3-12 months for infants, 1-5 years for toddlers.
|
|
122
|
+
* @property {GenderType|Text} suggestedGender The suggested gender of the intended user or audience, for example "male", "female", or "unisex".
|
|
123
|
+
* @property {QuantitativeValue} suggestedMeasurement A suggested range of body measurements for the intended audience or user, for example inseam between 32 and 34 inches or
|
|
124
|
+
* height between 170 and 190 cm. Typically found on a size chart for wearable products.
|
|
125
|
+
*/ /**
|
|
126
|
+
* Available stock for the variant. Present for PHYSICAL products only.
|
|
127
|
+
* @typedef {object} ProductStock
|
|
128
|
+
* @property {integer} quantity
|
|
129
|
+
* @property {boolean} unlimited
|
|
130
|
+
*/ /**
|
|
131
|
+
* Meta Information for SEO
|
|
132
|
+
* @typedef {object} MetaData
|
|
133
|
+
* @property {string} title
|
|
134
|
+
* @property {string} description
|
|
135
|
+
*/ /**
|
|
136
|
+
* @typedef {"newborn" | "infant" | "toddler" | "kids" | "adult"} AgeGroupEnum
|
|
137
|
+
* @typedef {"male" | "female" | "unisex"} GenderEnum
|
|
138
|
+
*/ /**
|
|
139
|
+
* Demographics characteristics
|
|
140
|
+
* @typedef {object} Demographics
|
|
141
|
+
* @property {boolean} adultOriented
|
|
142
|
+
* @property {AgeGroupEnum} age_group
|
|
143
|
+
* @property {GenderEnum} gender
|
|
144
|
+
*/ /**
|
|
145
|
+
* List of product ID's for various platforms
|
|
146
|
+
* @typedef {object} PlatformIDs
|
|
147
|
+
* @property {Text} squarespaceId
|
|
148
|
+
* @property {Text} googleMerchantId
|
|
149
|
+
* @property {Text} shopifyId
|
|
150
|
+
*/ /**
|
|
151
|
+
* Squarespace Specific Data
|
|
152
|
+
* @typedef {object} SquarespaceDataObject
|
|
153
|
+
* @property {Text} storePageId
|
|
154
|
+
*/ /**
|
|
155
|
+
* List of Platform Specific Data
|
|
156
|
+
* @typedef {object} PlatformData
|
|
157
|
+
* @property {SquarespaceDataObject} squarespaceData
|
|
158
|
+
*/ /**
|
|
159
|
+
* @typedef {object} AttributeValueObject
|
|
160
|
+
* @property {Text} condition
|
|
161
|
+
* @property {Array.Text} tags
|
|
162
|
+
* @property {Array.Text} colors
|
|
163
|
+
* @property {Array.Text} materials
|
|
164
|
+
* @property {Array.Text} patterns
|
|
165
|
+
* @property {string} custom_label_0
|
|
166
|
+
* @property {string} custom_label_1
|
|
167
|
+
* @property {string} custom_label_2
|
|
168
|
+
* @property {string} custom_label_3
|
|
169
|
+
* @property {string} custom_label_4
|
|
170
|
+
*/ /**
|
|
171
|
+
* @typedef {object} VideoImage
|
|
172
|
+
* @property {URL} video_link
|
|
173
|
+
*/ /**
|
|
174
|
+
* @typedef {object} VirtualModel
|
|
175
|
+
* @property {URL} virtual_model_link
|
|
176
|
+
*/ /**
|
|
177
|
+
* Media Related Data
|
|
178
|
+
* @typedef {object} MediaObject
|
|
179
|
+
* @property {Array.ProductImage} images
|
|
180
|
+
* @property {VideoImage} video_image
|
|
181
|
+
* @property {VirtualModel} virtual_model
|
|
182
|
+
*/ /**
|
|
183
|
+
* variant record (including inventory and pricing)
|
|
184
|
+
* @typedef {object} PhysicalProductVariant
|
|
185
|
+
* @property {PlatformIDs} platformIds
|
|
186
|
+
* @property {string} sku
|
|
187
|
+
* @property {ProductImage} image Image associated with this variant
|
|
188
|
+
* @property {FullProductPricing} pricing
|
|
189
|
+
* @property {ProductStock} stock
|
|
190
|
+
* @property {Array.AttributeValue} attributes array of attribute/value pairs for a variant
|
|
191
|
+
* @property {ProductMeasurements} shippingMeasurements
|
|
192
|
+
* @property {string} gtin Global Trade Item Number
|
|
193
|
+
* @property {string} mpn manufacturer part number
|
|
194
|
+
* @property {ProductMeasurements} productMeasurements
|
|
195
|
+
* @property {SizeSpecification} sizeSpecification
|
|
196
|
+
* @property {"in_stock"|"out_of_stock"|"preorder"|"backorder"} availability
|
|
197
|
+
* Accurately submit the product's availability and match the availability
|
|
198
|
+
* from your landing page, checkout pages, and structured data (for
|
|
199
|
+
* example, “in_stock” or “out_of_stock” in your Schema.org markup).
|
|
200
|
+
* If an item is out of stock, the price must still be clearly visible
|
|
201
|
+
* on the landing page.
|
|
202
|
+
* Provide the availability date [availability_date] attribute if you
|
|
203
|
+
* submit preorder [preorder] or backorder [backorder] as the availability value.
|
|
204
|
+
* @property {string|ISO8601} availability_date
|
|
205
|
+
* Use this attribute if your product's availability is set to preorder.
|
|
206
|
+
* Provide a value up to one year in the future.
|
|
207
|
+
* The availability date should also be added to the product’s landing
|
|
208
|
+
* page and be clear to your customers (for example, “May 6, 2023”).
|
|
209
|
+
* If an exact date can’t be provided, you can use an estimated date
|
|
210
|
+
* (for example, “May 2023”).
|
|
211
|
+
*/ /**
|
|
212
|
+
* a product record
|
|
213
|
+
* @typedef {object} Product
|
|
214
|
+
* @property {?string} Id Database Id of document (redundant for convenience)
|
|
215
|
+
* @property {?string} refPath if from database, full path to document
|
|
216
|
+
* @property {PlatformIDs} platformIds
|
|
217
|
+
* @property {PlatformData} platformData
|
|
218
|
+
* @property {string} name name for the Product
|
|
219
|
+
* @property {string} short_name name for the Product
|
|
220
|
+
* @property {string} description Basic description of the product
|
|
221
|
+
* @property {string} short_description
|
|
222
|
+
* @property {string} google_product_category
|
|
223
|
+
* @property {?string} product_type "casual google_product_category"
|
|
224
|
+
* @property {Text|BrandObject} brand
|
|
225
|
+
* The brand(s) associated with a product or service, or the brand(s) maintained by an organization or business user.
|
|
226
|
+
* @property {Demographics} demographics
|
|
227
|
+
* @property {AttributeValueObject} attributes array of attribute/value pairs for a product
|
|
228
|
+
* @property {Recipe_Data} recipe pricing and fabrication data
|
|
229
|
+
* @property {MediaObject} mediaObject
|
|
230
|
+
* @property {MobileInfo} mobileInfo
|
|
231
|
+
* @property {boolean} isVisible
|
|
232
|
+
* @property {MetaData} seoOptions
|
|
233
|
+
* @property {string} URL
|
|
234
|
+
* @property {string} urlSlug
|
|
235
|
+
* @property {Array.string} variantAttributes
|
|
236
|
+
* @property {Array.PhysicalProductVariant} variants
|
|
237
|
+
*/ /**
|
|
238
|
+
* @readonly
|
|
239
|
+
* @constant
|
|
240
|
+
* @type {Product}
|
|
241
|
+
* @default
|
|
242
|
+
*/ const $e615241e8e7f6b5a$var$ProductDefault = {
|
|
243
|
+
platformIds: {
|
|
244
|
+
squarespaceId: null,
|
|
245
|
+
googleMerchantId: null,
|
|
246
|
+
shopifyId: null
|
|
247
|
+
},
|
|
248
|
+
platformData: {
|
|
249
|
+
squarespaceData: {
|
|
250
|
+
storePageId: null
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
name: null,
|
|
254
|
+
short_name: null,
|
|
255
|
+
description: null,
|
|
256
|
+
short_description: null,
|
|
257
|
+
google_product_category: null,
|
|
258
|
+
product_type: null,
|
|
259
|
+
brand: {
|
|
260
|
+
aggregate_rating: null,
|
|
261
|
+
logo: null,
|
|
262
|
+
review: {},
|
|
263
|
+
slogan: null,
|
|
264
|
+
name: null
|
|
265
|
+
},
|
|
266
|
+
demographics: {
|
|
267
|
+
adultOriented: false,
|
|
268
|
+
age_group: null,
|
|
269
|
+
gender: null
|
|
270
|
+
},
|
|
271
|
+
attributes: [],
|
|
272
|
+
recipe: {
|
|
273
|
+
markups: null,
|
|
274
|
+
projectQ: false,
|
|
275
|
+
created: null,
|
|
276
|
+
modified: null
|
|
277
|
+
},
|
|
278
|
+
mediaObject: {
|
|
279
|
+
images: [],
|
|
280
|
+
video_image: null,
|
|
281
|
+
virtual_model: null
|
|
282
|
+
},
|
|
283
|
+
mobileInfo: null,
|
|
284
|
+
isVisible: true,
|
|
285
|
+
type: "PHYSICAL",
|
|
286
|
+
seoOptions: {
|
|
287
|
+
title: null,
|
|
288
|
+
description: null
|
|
289
|
+
},
|
|
290
|
+
tags: [
|
|
291
|
+
""
|
|
292
|
+
],
|
|
293
|
+
materials: [
|
|
294
|
+
""
|
|
295
|
+
],
|
|
296
|
+
patterns: [
|
|
297
|
+
""
|
|
298
|
+
],
|
|
299
|
+
URL: null,
|
|
300
|
+
urlSlug: null,
|
|
301
|
+
variantAttributes: [],
|
|
302
|
+
variants: []
|
|
303
|
+
};
|
|
304
|
+
/**
|
|
305
|
+
* Form to create test data
|
|
306
|
+
* @readonly
|
|
307
|
+
* @constant
|
|
308
|
+
* @type {Product}
|
|
309
|
+
* @default
|
|
310
|
+
*/ const $e615241e8e7f6b5a$var$ProductDataForm = {
|
|
311
|
+
Id: `string.uuid`,
|
|
312
|
+
refPath: null,
|
|
313
|
+
name: `commerce.product`,
|
|
314
|
+
description: `commerce.productDescription`,
|
|
315
|
+
sku: `commerce.isbn:${(0, $fefa9c41cb73ae0b$export$dbb3cd0a4caa6254)}`,
|
|
316
|
+
markups: `subrecord:${(0, $fefa9c41cb73ae0b$export$1bfdae073fb20e6c)}`,
|
|
317
|
+
projectQ: `checkbox`
|
|
318
|
+
};
|
|
319
|
+
/**
|
|
320
|
+
* Form to enter MINIMAL product data to start creation
|
|
321
|
+
* @readonly
|
|
322
|
+
* @constant
|
|
323
|
+
* @type {Product}
|
|
324
|
+
* @default
|
|
325
|
+
*/ const $e615241e8e7f6b5a$var$ProductDefaultForm = {
|
|
326
|
+
Id: `hidden`,
|
|
327
|
+
refPath: `hidden`,
|
|
328
|
+
name: "text",
|
|
329
|
+
description: "textarea",
|
|
330
|
+
sku: "text"
|
|
331
|
+
};
|
|
332
|
+
(0, $lRpTb$Forms).Base[0, $fefa9c41cb73ae0b$export$e36553b0ff5db35a] = $e615241e8e7f6b5a$var$ProductDefault;
|
|
333
|
+
(0, $lRpTb$Forms).BaseForm[0, $fefa9c41cb73ae0b$export$e36553b0ff5db35a] = $e615241e8e7f6b5a$var$ProductDefaultForm;
|
|
334
|
+
(0, $lRpTb$Forms).CreateForm[0, $fefa9c41cb73ae0b$export$e36553b0ff5db35a] = $e615241e8e7f6b5a$var$ProductDefaultForm;
|
|
335
|
+
(0, $lRpTb$Forms).Data[0, $fefa9c41cb73ae0b$export$e36553b0ff5db35a] = $e615241e8e7f6b5a$var$ProductDataForm;
|
|
336
|
+
(0, $lRpTb$Forms).Summarize[0, $fefa9c41cb73ae0b$export$e36553b0ff5db35a] = $e615241e8e7f6b5a$var$summarizeProduct;
|
|
337
|
+
(0, $lRpTb$Forms).Save[0, $fefa9c41cb73ae0b$export$e36553b0ff5db35a] = $e615241e8e7f6b5a$var$updateProduct;
|
|
338
|
+
(0, $lRpTb$Forms).SearchBy[0, $fefa9c41cb73ae0b$export$e36553b0ff5db35a] = "name";
|
|
339
|
+
async function $e615241e8e7f6b5a$export$9c734a715e6666d0() {
|
|
340
|
+
//get a blank Product Record
|
|
341
|
+
//write it to database, saving reference
|
|
342
|
+
//copy user stages to product stages
|
|
343
|
+
//We return the product information - but most applications will use database listeners
|
|
344
|
+
}
|
|
345
|
+
//////////////////////////////////////////////////////////////////////
|
|
346
|
+
// record operations
|
|
347
|
+
/**
|
|
348
|
+
* writes record back to database. Assumes only Id is valid
|
|
349
|
+
* @param {Product} product a partially-populated product record for updates
|
|
350
|
+
* @param {User} user minimal record of user this product belongs to
|
|
351
|
+
* @returns {promise.LineItem} a copy of the data written
|
|
352
|
+
*/ async function $e615241e8e7f6b5a$var$updateProduct(product, user = null) {
|
|
353
|
+
if (!(product?.refPath || user?.refPath)) {
|
|
354
|
+
console.log("no product specified to save LineItem");
|
|
355
|
+
//no root products
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
return (0, $lRpTb$updateRecord)((0, $lRpTb$fillForm)(product, (0, $fefa9c41cb73ae0b$export$e36553b0ff5db35a)), user, (0, $fefa9c41cb73ae0b$export$e36553b0ff5db35a));
|
|
359
|
+
}
|
|
360
|
+
//////////////////////////////////////////////////////////////////////
|
|
361
|
+
// utilities
|
|
362
|
+
/**
|
|
363
|
+
* Returns a standardized formatted name string
|
|
364
|
+
* @param {Unit}
|
|
365
|
+
* @returns {string} formatted name string
|
|
366
|
+
*/ function $e615241e8e7f6b5a$var$summarizeProduct(product) {
|
|
367
|
+
return `${product.name} ${product.description}`;
|
|
368
|
+
}
|
|
369
|
+
function $e615241e8e7f6b5a$export$d4a471daa895146b(child) {
|
|
370
|
+
return (0, $9ab66828811feaa2$export$9536a88c96a1be48)(child, (0, $fefa9c41cb73ae0b$export$e36553b0ff5db35a));
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
export {$e615241e8e7f6b5a$export$9c734a715e6666d0 as createProduct, $e615241e8e7f6b5a$export$d4a471daa895146b as makeProductFromChild, $e409a6a48e9bf1c0$export$4059922dac929494 as GoogleAPIProductMap, $63eb266a363bf697$export$8f68ab01093b41d6 as JSONProductFeedToItemMapping, $63eb266a363bf697$export$c736243f342fb27b as squarespaceFeedTest};
|
|
375
|
+
//# sourceMappingURL=InventoryLogic.70925a32.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["business/Product/index.js"],"sourcesContent":["/**\n * Typedefs, constants, support functions and database operations related to Products\n * @module Product\n */\nimport { updateRecord } from \"@leaddreamer/firebase-wrapper\";\nimport { Forms, fillForm } from \"@leaddreamer/staticforms\";\n\nimport { PRODUCT, MARKUPS, ISBN_LENGTH } from \"../boilerplate/index.js\";\nimport { typedRecordFromChild } from \"../Utilities/index.js\"\n\n//////////////////////////////////////////////////////////////////////\n// Constants\n\n/**\n * \"recipe\" related values - build-stage markups, product/project Flag, created/modified dates\n * @typedef {object} Recipe_Data\n * @property {module:Markups~Stage} markups\n * @property {boolean} projectQ flag for product/project\n * @property {dateTime} created\n * @property {dateTime} modified\n */\n\n/**\n * A list of attributes for a product\n * @typedef {Array.String} AttributeList\n */\n\n/**\n * Array of attribute name/value pairs\n * @typedef {object} AttributeValue\n * @property {string} attibuteName attribute name from attribute list\n * @property {string} value value for the particular attribute\n */\n\n/**\n * @typedef\n */\n\n/**\n * Image Descriptor\n * @typedef {object} ProductImage\n * @property {string} altText alt text for the image - SEO etc\n * @property {Array.string} availableFormats Available image sizes.\n * @property {string} id unique id for this productImage\n * @property {integer} orderIndex Position of the image in the product's image list.\n * @property {object} originalSize Image size when first uploaded.\n * @property {MetaData} seoOptions\n * @property {string} URL Absolute URL of the hosted image.\n */\n\n/**\n * a Brand Object\n * @typedef {object} BrandObject\n * @property {?string} Id Database Id of document (redundant for convenience)\n * @property {?string} refPath if from database, full path to document\n * @property {?AggregateRatingsValue} aggregateRating\n * @property {?URL|ImageObject} logo\n * @property {ReviewObject} review A review of the item. Supersedes reviews\n * @property {text} slogan A slogan or motto associated with the item.\n * @property {Name} name The name of the brand.\n */\n\n/**\n * Currency Description ISO 4217 currency code\n * @typedef {object} CurrencyDescription\n * @property {string} currencyCode\n * @property {integer} defaultFractionDigits\n * @property {string} displayName\n * @property {string} numericCodeAsString\n * @property {string} symbol\n */\n\n/**\n * Monetary Value Specification\n * @typedef {object} MonetaryValue\n * @property {CurrencyDescription} currencyDescription\n * @property {decimal} value Decimal monetary value\n * @property {Date} effectiveDate\n */\n\n/**\n * Pricing Object\n * @typedef {object} FullProductPricing\n * @property {MonetaryValue} basePrice\n * @property {boolean} onSale\n * @property {MonetaryValue} salePrice\n */\n\n/**\n * Dimensions Object\n * @typedef {object} ProductDimensions\n * @property {float} height \n * @property {float} width \n * @property {float} length \n * @property {text} unit //ProductDimensionsUnit\n */\n\n/**\n * Price Object\n * @typedef {object} PriceObject\n * \n */\n\n/**\n * Weight Object\n * @typedef {object} ProductWeight\n * @property {text} unit //ProductWeightUnitEnum\n * @property {float} value\n */\n\n/**\n * Measurements of the variant when it's shipped. Present for PHYSICAL products only.\n * @typedef {object} ProductMeasurements\n * @property {ProductDimensions} dimensions\n * @property {ProductWeight} weight\n */\n\n/**\n * @typedef {object} QuantitativeValue\n * @property {Boolean | Number | text | StructuredValue} value\n * The value of a QuantitativeValue (including Observation) or property value node.\n * * For QuantitativeValue and MonetaryAmount, the recommended type for values is 'Number'.\n * * For PropertyValue, it can be 'Text', 'Number', 'Boolean', or 'StructuredValue'.\n * * Use values from 0123456789 (Unicode 'DIGIT ZERO' (U+0030) to 'DIGIT NINE' (U+0039)) rather than superficially similar Unicode symbols.\n * * Use '.' (Unicode 'FULL STOP' (U+002E)) rather than ',' to indicate a decimal point. Avoid using these symbols as a readability separator.\n * @property {number} maxValue The upper value of some characteristic or property.\n * @property {number} minValue The lower value of some characteristic or property.\n * @property {?Text} unitText A string or text indicating the unit of measurement. Useful if you cannot provide a standard unit code for unitCode\n * @property {?Text | URL} unitCode \n * The unit of measurement given using the UN/CEFACT Common Code (3 characters) or a URL. Other codes than the UN/CEFACT Common Code may be used with a prefix followed by a colon\n * \n */\n\n/**\n * @typedef {object} SizeSpecification\n * @property {Text} type \"SizeSpecification\"\n * @property {QuantitativeValue} hasMeasurement\n * @property {Array.SizeGroupEnumeration|SizeGroupEnumeration|Text} sizeGroup\n * The size group (also known as \"size type\") for a product's size. Size groups are common in the fashion industry to define size\n * segments and suggested audiences for wearable products. Multiple values can be combined, for example \"men's big and tall\", \"petite maternity\" or \"regular\".\n * @property {Array.SizeSystemEnumeration|SizeSystemEnumeration|Text} sizeSystem\n * The size system used to identify a product's size. Typically either a standard (for example, \"GS1\" or \"ISO-EN13402\"), country\n * code (for example \"US\" or \"JP\"), or a measuring system (for example \"Metric\" or \"Imperial\").\n * @property {QuantitativeValue} suggestedAge The age or age range for the intended audience or user, for example 3-12 months for infants, 1-5 years for toddlers.\n * @property {GenderType|Text} suggestedGender The suggested gender of the intended user or audience, for example \"male\", \"female\", or \"unisex\".\n * @property {QuantitativeValue} suggestedMeasurement A suggested range of body measurements for the intended audience or user, for example inseam between 32 and 34 inches or\n * height between 170 and 190 cm. Typically found on a size chart for wearable products.\n */\n\n/**\n * Available stock for the variant. Present for PHYSICAL products only.\n * @typedef {object} ProductStock\n * @property {integer} quantity\n * @property {boolean} unlimited\n */\n\n/**\n * Meta Information for SEO\n * @typedef {object} MetaData\n * @property {string} title\n * @property {string} description\n */\n\n/**\n * @typedef {\"newborn\" | \"infant\" | \"toddler\" | \"kids\" | \"adult\"} AgeGroupEnum\n * @typedef {\"male\" | \"female\" | \"unisex\"} GenderEnum\n */\n\n/**\n * Demographics characteristics\n * @typedef {object} Demographics\n * @property {boolean} adultOriented\n * @property {AgeGroupEnum} age_group\n * @property {GenderEnum} gender\n */\n\n/**\n * List of product ID's for various platforms\n * @typedef {object} PlatformIDs\n * @property {Text} squarespaceId\n * @property {Text} googleMerchantId\n * @property {Text} shopifyId\n */\n\n/**\n * Squarespace Specific Data\n * @typedef {object} SquarespaceDataObject\n * @property {Text} storePageId\n */\n\n/**\n * List of Platform Specific Data\n * @typedef {object} PlatformData\n * @property {SquarespaceDataObject} squarespaceData\n */\n\n/**\n * @typedef {object} AttributeValueObject\n * @property {Text} condition\n * @property {Array.Text} tags\n * @property {Array.Text} colors\n * @property {Array.Text} materials\n * @property {Array.Text} patterns\n * @property {string} custom_label_0\n * @property {string} custom_label_1\n * @property {string} custom_label_2\n * @property {string} custom_label_3\n * @property {string} custom_label_4\n */\n\n/**\n * @typedef {object} VideoImage\n * @property {URL} video_link\n */\n\n/**\n * @typedef {object} VirtualModel\n * @property {URL} virtual_model_link\n */\n\n/**\n * Media Related Data\n * @typedef {object} MediaObject\n * @property {Array.ProductImage} images\n * @property {VideoImage} video_image\n * @property {VirtualModel} virtual_model \n */\n\n/**\n * variant record (including inventory and pricing)\n * @typedef {object} PhysicalProductVariant\n * @property {PlatformIDs} platformIds\n * @property {string} sku\n * @property {ProductImage} image Image associated with this variant\n * @property {FullProductPricing} pricing\n * @property {ProductStock} stock\n * @property {Array.AttributeValue} attributes array of attribute/value pairs for a variant\n * @property {ProductMeasurements} shippingMeasurements\n * @property {string} gtin Global Trade Item Number\n * @property {string} mpn manufacturer part number\n * @property {ProductMeasurements} productMeasurements\n * @property {SizeSpecification} sizeSpecification\n * @property {\"in_stock\"|\"out_of_stock\"|\"preorder\"|\"backorder\"} availability\n * Accurately submit the product's availability and match the availability\n * from your landing page, checkout pages, and structured data (for\n * example, “in_stock” or “out_of_stock” in your Schema.org markup).\n * If an item is out of stock, the price must still be clearly visible\n * on the landing page.\n * Provide the availability date [availability_date] attribute if you\n * submit preorder [preorder] or backorder [backorder] as the availability value.\n * @property {string|ISO8601} availability_date\n * Use this attribute if your product's availability is set to preorder.\n * Provide a value up to one year in the future.\n * The availability date should also be added to the product’s landing\n * page and be clear to your customers (for example, “May 6, 2023”).\n * If an exact date can’t be provided, you can use an estimated date\n * (for example, “May 2023”).\n */\n\n/**\n * a product record\n * @typedef {object} Product\n * @property {?string} Id Database Id of document (redundant for convenience)\n * @property {?string} refPath if from database, full path to document\n * @property {PlatformIDs} platformIds\n * @property {PlatformData} platformData\n * @property {string} name name for the Product\n * @property {string} short_name name for the Product\n * @property {string} description Basic description of the product\n * @property {string} short_description\n * @property {string} google_product_category\n * @property {?string} product_type \"casual google_product_category\"\n * @property {Text|BrandObject} brand\n * The brand(s) associated with a product or service, or the brand(s) maintained by an organization or business user.\n * @property {Demographics} demographics\n * @property {AttributeValueObject} attributes array of attribute/value pairs for a product\n * @property {Recipe_Data} recipe pricing and fabrication data\n * @property {MediaObject} mediaObject\n * @property {MobileInfo} mobileInfo\n * @property {boolean} isVisible\n * @property {MetaData} seoOptions\n * @property {string} URL\n * @property {string} urlSlug\n * @property {Array.string} variantAttributes\n * @property {Array.PhysicalProductVariant} variants\n */\n\n/**\n * @readonly\n * @constant\n * @type {Product}\n * @default\n */\nconst ProductDefault = {\n platformIds: {\n squarespaceId: null,\n googleMerchantId: null,\n shopifyId: null\n },\n platformData: {\n squarespaceData: {\n storePageId: null\n }\n },\n name: null,\n short_name: null,\n description: null,\n short_description: null,\n google_product_category: null,\n product_type: null,\n brand: {\n aggregate_rating: null,\n logo: null,\n review: {},\n slogan: null,\n name: null\n },\n demographics: {\n adultOriented: false,\n age_group: null,\n gender: null\n },\n attributes: [],\n recipe: {\n markups: null,\n projectQ: false,\n created: null,\n modified: null,\n },\n mediaObject: {\n images: [],\n video_image: null,\n virtual_model: null\n },\n mobileInfo: null,\n isVisible: true,\n type: \"PHYSICAL\",\n seoOptions: {\n title: null,\n description: null,\n },\n tags: [\"\"],\n materials: [\"\"],\n patterns: [\"\"],\n URL: null,\n urlSlug: null,\n variantAttributes: [],\n variants: []\n};\n\n/**\n * Form to create test data\n * @readonly\n * @constant\n * @type {Product}\n * @default\n */\nconst ProductDataForm = {\n Id: `string.uuid`,\n refPath: null,\n name: `commerce.product`,\n description: `commerce.productDescription`,\n sku: `commerce.isbn:${ISBN_LENGTH}`,\n markups: `subrecord:${MARKUPS}`,\n projectQ: `checkbox`\n};\n\n/**\n * Form to enter MINIMAL product data to start creation\n * @readonly\n * @constant\n * @type {Product}\n * @default\n */\nconst ProductDefaultForm = {\n Id: `hidden`,\n refPath: `hidden`,\n name: \"text\",\n description: \"textarea\",\n sku: \"text\",\n};\n\nForms.Base[PRODUCT] = ProductDefault;\nForms.BaseForm[PRODUCT] = ProductDefaultForm;\nForms.CreateForm[PRODUCT] = ProductDefaultForm;\nForms.Data[PRODUCT] = ProductDataForm;\nForms.Summarize[PRODUCT] = summarizeProduct;\nForms.Save[PRODUCT] = updateProduct;\nForms.SearchBy[PRODUCT] = \"name\";\n\n//////////////////////////////////////////////////////////////////////\n// business operations\n\n/**\n * Creates a new Blank Product\n * @param {UserObject} user minimal record of user this commodity belongs to (if any)\n * @returns {Promise<void>}\n */\n\nexport async function createProduct() {\n //get a blank Product Record\n //write it to database, saving reference\n //copy user stages to product stages\n //We return the product information - but most applications will use database listeners\n};\n\n\n//////////////////////////////////////////////////////////////////////\n// record operations\n\n/**\n * writes record back to database. Assumes only Id is valid\n * @param {Product} product a partially-populated product record for updates\n * @param {User} user minimal record of user this product belongs to\n * @returns {promise.LineItem} a copy of the data written\n */\nasync function updateProduct(product, user = null) {\n if (!(product?.refPath || user?.refPath)) {\n console.log(\"no product specified to save LineItem\");\n //no root products\n return null;\n };\n\n return updateRecord(\n fillForm(product, PRODUCT), //saves only APPROPRIATE fields -does NOT populate missing fields\n user,\n PRODUCT\n );\n}\n\n//////////////////////////////////////////////////////////////////////\n// utilities\n\n/**\n * Returns a standardized formatted name string\n * @param {Unit}\n * @returns {string} formatted name string\n */\nfunction summarizeProduct(product) {\n return `${product.name} ${product.description}`;\n}\n/**\n * @param {Record} child a record assumed to be a leaf/child\n * @returns {Record}\n */\nexport function makeProductFromChild(child) {\n return typedRecordFromChild(child, PRODUCT);\n}\n\nexport * from \"./GoogleMerchantAPI.js\";\nexport * from \"./Squarespace.js\"\n"],"names":[],"version":3,"file":"InventoryLogic.70925a32.js.map"}
|